xml - 试图在同一个 XML 文档中使用 XSLT 和 Key 函数查找相关值
问题描述
大家好,
希望您能帮助我解决以下问题。我对 XML 有一点了解,通过反复试验和阅读 Stack Overflow 上的项目,我设法创建了一个有效的 XSLT。唯一不起作用的是获取项目 ID (AI0567) 旁边的项目描述 ("BlaBla")。所以这个描述必须出现在“ns0:CarrierContent”行的级别上。
这里的问题(?)是描述不是一个孩子,它在同一级别。任何人都知道这是否可能?先感谢您!
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<ns0:Message xmlns:ns0="####">
<ns0:Header>
</ns0:Header>
<ns0:Customers>
<ns0:Customer>
<ns0:Carriers>
<ns0:Carrier>
<ns0:ContentLines>
<ns0:CarrierContent>
<ns0:CustomerItemNo>AI0567</ns0:CustomerItemNo>
</ns0:CarrierContent>
</ns0:ContentLines>
</ns0:Carrier>
</ns0:Carriers>
<ns0:Items>
<ns0:Item>
<ns0:No>AI0567</ns0:No>
<ns0:Description>BlaBla</ns0:Description>
</ns0:Item>
</ns0:Items>
</ns0:Customer>
</ns0:Customers>
</ns0:Message>
XSLT:
<?xml version="1.0" encoding="utf-8"?>
<?mso-application progid=”Excel.Sheet”?>
<xsl:stylesheet version="2.0"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:ns0="###">
<xsl:template match="/">
<xsl:processing-instruction name="mso-application">
<xsl:text>progid="Excel.Sheet"</xsl:text>
</xsl:processing-instruction>
<Workbook>
<Worksheet ss:Name="Page1">
<Table>
<xsl:call-template name="XMLToXSL" />
</Table>
</Worksheet>
</Workbook>
</xsl:template>
<xsl:template name="XMLToXSL">
<xsl:processing-instruction name="mso-application">
<xsl:text>progid="Excel.Sheet"</xsl:text>
</xsl:processing-instruction>
<xsl:key name="DescriptionSearch" match="ns0:Message/ns0:Customers/ns0:Customer/ns0:Items/ns0:Item" use="@ns0:Message/ns0:Customers/ns0:Customer/ns0:Items/ns0:Item/ns0:No" />
<xsl:for-each select="/">
<Row>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="ns0:Message/ns0:Customers/ns0:Customer/ns0:Carriers/ns0:Carrier/ns0:ContentLines/ns0:CarrierContent/ns0:CustomerItemNo" />
</Data>
</Cell>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="ns0:Message/ns0:Customers/ns0:Customer/ns0:Carriers/ns0:Carrier/ns0:ContentLines/ns0:CarrierContent/ns0:ExternalCustomerItemNo" />
</Data>
</Cell>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="key('DescriptionSearch',@ns0:Message/ns0:Customers/ns0:Customer/ns0:Carriers/ns0:Carrier/ns0:ContentLines/ns0:CarrierContent/ns0:CustomerItemNo)" />
</Data>
</Cell>
</Row>
</xsl:for-each>
</xsl:template>
<xsl:template match="/ns0:Message">
</xsl:template>
</xsl:stylesheet>
解决方案
定义有很多问题xsl:key
xsl:key
需要是直接的孩子,xsl:stylesheet
而不是在里面xsl:template
- “use”值以
@
which 开头,表示属性,但ns0:message
不是属性(如果是,则后面不会有子元素) - “使用”值应该与匹配的内容相关。
这意味着,你xsl:key
应该看起来像这样
<xsl:key name="DescriptionSearch" match="ns0:Message/ns0:Customers/ns0:Customer/ns0:Items/ns0:Item" use="ns0:No" />
实际上,在这种情况下,您可以将其简化为此,因为您不需要指定匹配的完整路径(除非其他地方有您不需要匹配的具有不同路径的项目)
<xsl:key name="DescriptionSearch" match="ns0:Item" use="ns0:No" />
至于使用key,你的表达方式需要是这样的(再次注意@
as的使用是怎么去掉的)
<xsl:value-of select="key('DescriptionSearch',ns0:Message/ns0:Customers/ns0:Customer/ns0:Carriers/ns0:Carrier/ns0:ContentLines/ns0:CarrierContent/ns0:CustomerItemNo)/ns0:Description" />
所以,你的 XSLT 可能看起来像这样......
<xsl:stylesheet version="2.0"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:ns0="####">
<xsl:key name="DescriptionSearch" match="ns0:Item" use="ns0:No" />
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<xsl:processing-instruction name="mso-application">
<xsl:text>progid="Excel.Sheet"</xsl:text>
</xsl:processing-instruction>
<Workbook>
<Worksheet ss:Name="Page1">
<Table>
<xsl:call-template name="XMLToXSL" />
</Table>
</Worksheet>
</Workbook>
</xsl:template>
<xsl:template name="XMLToXSL">
<xsl:for-each select="/">
<Row>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="ns0:Message/ns0:Customers/ns0:Customer/ns0:Carriers/ns0:Carrier/ns0:ContentLines/ns0:CarrierContent/ns0:CustomerItemNo" />
</Data>
</Cell>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="ns0:Message/ns0:Customers/ns0:Customer/ns0:Carriers/ns0:Carrier/ns0:ContentLines/ns0:CarrierContent/ns0:ExternalCustomerItemNo" />
</Data>
</Cell>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="key('DescriptionSearch',ns0:Message/ns0:Customers/ns0:Customer/ns0:Carriers/ns0:Carrier/ns0:ContentLines/ns0:CarrierContent/ns0:CustomerItemNo)/ns0:Description" />
</Data>
</Cell>
</Row>
</xsl:for-each>
</xsl:template>
<xsl:template match="/ns0:Message">
</xsl:template>
</xsl:stylesheet>
但我可能会将最终模板简化为此(因为这允许您的 XML 可能包含多个客户
<xsl:template name="XMLToXSL">
<xsl:for-each select="/ns0:Message/ns0:Customers/ns0:Customer/ns0:Carriers/ns0:Carrier/ns0:ContentLines/ns0:CarrierContent">
<Row>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="ns0:CustomerItemNo" />
</Data>
</Cell>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="ns0:ExternalCustomerItemNo" />
</Data>
</Cell>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="key('DescriptionSearch', ns0:CustomerItemNo)/ns0:Description" />
</Data>
</Cell>
</Row>
</xsl:for-each>
</xsl:template>
<xsl:template match="/ns0:Message">
</xsl:template>
推荐阅读
- javascript - 需要将表单字段转换为整数
- youtube-api - id list API 获取的 YT.videos 的 id 数量限制是多少?
- python - 如何在python中按日期对数组进行排序?
- c - 使用 scanf 直到 EOF 将值插入节点
- python - 使用 ffmpeg 和 python 将视频中的所有音频流提取到单独的音频文件中
- javascript - 如何在 Gatsby 中对 graphql 查询的过滤结果进行单元测试?
- arrays - 如何使用流 (java.util.stream) 处理嵌套 for 循环中的数组?
- ruby - 附加到 CSV 文件,我可以使用 seek 来确定是否应该写入标题?有没有更好的办法?
- reactjs - 反应应用程序上的 Apollo 客户端缓存问题
- python - 如何使函数打印更多结果?