如何仅从 XML 输入中复制或匹配具有命名空间的选定元素,然后同时删除命名空间
下面给出的是我的 XML 输入。如何使用 XSL 复制或匹配要在 XML 输出中反映的选定元素。
逻辑的总体思路应该是仅指定我感兴趣的元素,而不是指定我不喜欢包含在输出中的元素。我想要在输出 XML 中反映的元素始终存在于 XML 输入中。其余元素根据系统生成的内容而有所不同,因此我不能只指定要删除的内容。
通过复制,我可以在没有输入名称空间的情况下做到这一点,但是当名称空间存在时,代码无法工作。
我找到了一种删除名称空间的方法,但与副本结合使用时效果不佳。我对 XSL 的行为感到非常困惑。
请耐心等待我的询问,我对 XML 和 XSL 非常陌生,我被分配到这项任务是因为我们团队中没有人有使用 XML 的经验。先感谢您。
XML 输入:
<Transaction xmlns="http://www.test.com/rdc.xsd">
<Transaction>
<StoreName id="aa">STORE A</StoreName>
<TransNo>TXN0001</TransNo>
<RegisterNo>REG001</RegisterNo>
<Items>
<Item id="1">
<ItemID>A001</ItemID>
<ItemDesc>Keychain</ItemDesc>
</Item>
<Item id="2">
<ItemID>A002</ItemID>
<ItemDesc>Wallet</ItemDesc>
</Item>
</Items>
<IDONTLIKETHIS_1>
<STOREXXX>XXX</STOREXXX>
<TRANSXXX>YYY</TRANSXXX>
</IDONTLIKETHIS_1>
<IDONTLIKETHIS_2>
<STOREXXX>XXX</STOREXXX>
<TRANSXXX>YYY</TRANSXXX>
</IDONTLIKETHIS_2>
</Transaction>
</Transaction>
所需的输出:
<Transaction>
<Transaction>
<StoreName id="aa">STORE A</StoreName>
<TransNo>TXN0001</TransNo>
<RegisterNo>REG001</RegisterNo>
<Items>
<Item id="1">
<ItemID>A001</ItemID>
<ItemDesc>Keychain</ItemDesc>
</Item>
<Item id="2">
<ItemID>A002</ItemID>
<ItemDesc>Wallet</ItemDesc>
</Item>
</Items>
</Transaction>
</Transaction>
我已经尝试了下面的代码,但问题是我缺少第二个 Transaction 元素,并且 xmlns 属性存在于根元素中:
<xsl:template match="*">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="node()[not(self::*)]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="x:Transaction/x:StoreName"/>
<xsl:copy-of select="x:Transaction/x:TransNo"/>
<xsl:copy-of select="x:Transaction/x:RegisterNo"/>
<xsl:copy-of select="x:Transaction/x:Items"/>
</xsl:copy>
</xsl:template>
Given below is my XML input. How do I copy or match selected elements that I want to reflect in my XML output using XSL.
The general idea of the logic should be to specify only the elements I am interested instead of specifying the elements that I don't like to be included in the output. The elements that I want to reflect in my output XML are always present in the XML Inpput. The rest of the elements vary depending on what the system has generated and so I cannot just specify what to remove.
I was able to this without the namespace from the input by doing the copy-of, but when the namespace is present the code is not working.
I found a way to remove the namespace but when combined with the copy-of, didn't work as well. I am quite confused as to how XSL behaves.
Please bear with my inquiry, I'm very new to XML and XSL and I was assigned to this task because no one from our team had the experience working with XML. Thank you in advance.
XML Input:
<Transaction xmlns="http://www.test.com/rdc.xsd">
<Transaction>
<StoreName id="aa">STORE A</StoreName>
<TransNo>TXN0001</TransNo>
<RegisterNo>REG001</RegisterNo>
<Items>
<Item id="1">
<ItemID>A001</ItemID>
<ItemDesc>Keychain</ItemDesc>
</Item>
<Item id="2">
<ItemID>A002</ItemID>
<ItemDesc>Wallet</ItemDesc>
</Item>
</Items>
<IDONTLIKETHIS_1>
<STOREXXX>XXX</STOREXXX>
<TRANSXXX>YYY</TRANSXXX>
</IDONTLIKETHIS_1>
<IDONTLIKETHIS_2>
<STOREXXX>XXX</STOREXXX>
<TRANSXXX>YYY</TRANSXXX>
</IDONTLIKETHIS_2>
</Transaction>
</Transaction>
Desired Output:
<Transaction>
<Transaction>
<StoreName id="aa">STORE A</StoreName>
<TransNo>TXN0001</TransNo>
<RegisterNo>REG001</RegisterNo>
<Items>
<Item id="1">
<ItemID>A001</ItemID>
<ItemDesc>Keychain</ItemDesc>
</Item>
<Item id="2">
<ItemID>A002</ItemID>
<ItemDesc>Wallet</ItemDesc>
</Item>
</Items>
</Transaction>
</Transaction>
I've tried the code below but the problem with it is that I'm missing the second Transaction element and the xmlns attribute is present in the root element:
<xsl:template match="*">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="node()[not(self::*)]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="x:Transaction/x:StoreName"/>
<xsl:copy-of select="x:Transaction/x:TransNo"/>
<xsl:copy-of select="x:Transaction/x:RegisterNo"/>
<xsl:copy-of select="x:Transaction/x:Items"/>
</xsl:copy>
</xsl:template>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
此转换使用我们要在处理后复制的所有元素名称的列表:
应用于提供的 XML 文档时:
生成所需的正确结果:
请注意:与其他可能的解决方案相比,此解决方案的一个优点是包含管道分隔的元素名称列表的字符串可以作为外部指定的参数提供给转换,使其非常强大和灵活,并且无需随时更改代码从我们的白名单中包含新元素(或排除某些元素)。
This transformation uses a list of all names of elements that we want to copy after processing:
when applied to the provided XML document:
the wanted, correct result is produced:
Do note: One advantage of this solution over other possible solution is that the string containing the pipe-delimited list of element names can be provide as an externally-specified parameter to the transformation, making it very powerful and flexible and eliminating the need to alter the code any time we include new elements (or exclude some) from our white-list.
这行得通吗?
Would this work?
这似乎可以满足您的需要,但请阅读名称空间,因为我不确定您计划做的是否明智。
希望这有帮助,
肯
This seems to do what you need, but please read up on namespaces as I'm not sure that what you plan to do is all that sensible.
Hope this helps,
Ken