#xslt-2.0
#xslt-2.0
Вопрос:
Я новичок в использовании XSLT и столкнулся с проблемой с одной из моих программ. Я пытался решить эту проблему с помощью своих ограниченных знаний, но безрезультатно. Я пытаюсь обработать XML-файл, чтобы получить только части US. Данные содержат как китайскую, так и американскую части. Данные содержатся в повторяющихся узлах.
Я пробовал условные операторы, чтобы ограничить выбор только для получения идентификатора детали США. Тем не менее, я получаю идентификаторы для всех частей.
Это образец входного файла XML:
<Part>
<Part_ID>Comp-97531</Part_ID>
<Country>US</Country>
<Identification_Data>
<Product>Finished</Product>
<ID>12345678909876</ID>
<ID_Type>CHN-1</ID_Type>
<Identification_Data>
<Identification_Data>
<Product>Finished</Product>
<ID>123456789</ID>
<ID_Type>CHN-2</ID_Type>
</Identification_Data>
<Identification_Data>
<Product>Finished</Product>
<ID>13579</ID>
<ID_Type>CHN-3</ID_Type>
</Identification_Data>
<Identification_Data>
<Product>Finished</Product>
<ID>555555555</ID>
<ID_Type>USA-1</ID_Type>
</Identification_Data>
</Part>
<Part>
<Part_ID>Comp-95137</Part_ID>
<Country>US</Country>
<Identification_Data>
<Product>Finished</Product>
<ID>1234567812345</ID>
<ID_Type>CHN-1</ID_Type>
<Identification_Data>
<Identification_Data>
<Product>Finished</Product>
<ID>987654321</ID>
<ID_Type>CHN-2</ID_Type>
</Identification_Data>
<Identification_Data>
<Product>Finished</Product>
<ID>246810</ID>
<ID_Type>CHN-3</ID_Type>
</Identification_Data>
<Identification_Data>
<Product>Finished</Product>
<ID>777777777</ID>
<ID_Type>USA-1</ID_Type>
</Identification_Data>
</Part>
Это код XSLT, который я пытаюсь:
<xsl:template match="/">
<FILE>
<xsl:for-each select="Part">
<xsl:call-template name="ProductRecord"/>
</xsl:for-each>
</FILE>
</xsl:template>
<xsl:template name="ProductRecord">
<ID>
<xsl:choose>
<xsl:when test="Country = 'US'">
<xsl:if test="Identification_Data/ID_Type='USA-1'">
<xsl:value-of select="Identification_Data/ID"/>
</xsl:if>
</xsl:when>
</xsl:choose>
</ID>
</xsl:template>
Требование состоит в том, чтобы получать только детали, изготовленные в США, с ID_TYPE = USA-1 .
Используя код XSLT, я ожидаю только значения для ID_Type = USA-1, которые будут равны 555555555. Однако результат, который я получаю, выглядит следующим образом:
12345678909876 123456789 13579 555555555.
Как я могу ограничить выбор, чтобы показывать только данные, относящиеся к США?
Заранее спасибо за ваш ответ.
Ответ №1:
Прежде чем вы начнете возиться с инструкциями XSLT, вы должны начать понимать XPath как его язык выражений, и там вы могли бы просто выбрать //Part[Country = 'US']
, чтобы выбрать Part
элементы, для которых выполняется условие Country = 'US'
в предикате [Country = 'US']
.
Затем с выбранными Part
элементами в качестве контекстного узла вы можете выбрать Identification_Data[ID_Type = 'USA-1']/ID
, чтобы выбрать ID
дочерние элементы Identification_Data
элементов, для которых выполняется условие ID_Type = 'USA-1'
.
Чтобы использовать эти выражения XPath в XSLT, вы можете просто использовать
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:template match="root">
<xsl:apply-templates select="Part[Country = 'US']"/>
</xsl:template>
<xsl:template match="Part">
<xsl:copy-of select="Identification_Data[ID_Type = 'USA-1']/ID"/>
</xsl:template>
</xsl:stylesheet>
Пример на https://xsltfiddle .liberty-development.net/94rmq6q/1 .
Поэтому нет необходимости в каких-либо xsl:call-template
или xsl:choose
, достаточно простого выбора XPath и шаблонов сопоставления.
Обратите внимание, что мне пришлось исправить часть вашей разметки ввода, а также ввести контейнер корневых элементов для Part
элементов, поскольку обычно ввод XSLT представляет собой правильно сформированный XML-документ, а не последовательность Part
или другие элементы-братья и сестры.