如何使用 x-path 仅迭代 xml 中的第一级节点?
我需要遍历 XML 文件。根节点有几个子节点,我需要按原样复制子节点或执行某些操作。为此,我正在开发 XSLT。下面是一个示例源 XML:
<?xml version="1.0" encoding="utf-8"?>
<XDSDocumentEntry id="DOC01">
<author authorRole="XDSITEST_DICOM_INSTANCE_PUBLISHER" authorPerson="XDSITEST">Author</author>
<classCode displayName="Communication" codingScheme="Connect-a-thon classCodes">Communication</classCode>
<confidentialityCode displayName="Celebrity" codingScheme="Connect-a-thon confidentialityCodes">
</XDSDocumentEntry>
在此 XML 中,我需要选择节点 author、classCode 和 confidentialityCodes,但我得到的是 text() 节点使用这段代码:
<xsl:for-each select="node()"><!--<xsl:copy-of select="."/>-->
<!--<xsl:value-of select="local-name()"/>-->
<xsl:choose>
<xsl:when test="author">
do something
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
到目前为止我的结果是这样的:
author<author authorRole="XDSITEST_DICOM_INSTANCE_PUBLISHER" authorPerson="XDSITEST"
authorInstitution="Some institution"/>
classCode<classCode displayName="Communication" codingScheme="Connect-a-thon classCodes">Communication</classCode>
confidentialityCode<confidentialityCode displayName="Celebrity" codingScheme="Connect-a-thon confidentialityCodes">
C</confidentialityCode>
有什么提示吗?谢谢。
编辑
抱歉,有一个错误(我删除了)。
实际上,我为什么使用 for-each 是因为我需要的文档与除了几个节点之外完全相同。在上面的示例中,最终输出应如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<XDSDocumentEntry>
<author authorRole="XDSITEST_DICOM_INSTANCE_PUBLISHER" authorPerson="XDSITEST"
authorInstitution="Some institution"/>
<author>
<authorInstitution>
<organizationName>Some institution</organizationName>
</authorInstitution>
<authorRole>XDSITEST_DICOM_INSTANCE_PUBLISHER</authorRole>
<authorPerson>
<assigningAuthorityName>XDSITEST</assigningAuthorityName>
</authorPerson>
</author>
<classCode displayName="Communication" codingScheme="Connect-a-thon classCodes">Communication</classCode>
<confidentialityCode displayName="Celebrity" codingScheme="Connect-a-thon confidentialityCodes">
C</confidentialityCode>
</XDSDocumentEntry>
编辑 2
我按照@Martin 的建议创建了此模板。但我仍然如何选择节点名称“作者”?
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:choose>
<xsl:when test="local-name()=author">
a
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="node()|@*"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
I need to iterate through an XML file. The root node has a few children and I need to either copy the child as is or to do something. So I'm working on an XSLT to do so. Here's a sample source XML:
<?xml version="1.0" encoding="utf-8"?>
<XDSDocumentEntry id="DOC01">
<author authorRole="XDSITEST_DICOM_INSTANCE_PUBLISHER" authorPerson="XDSITEST">Author</author>
<classCode displayName="Communication" codingScheme="Connect-a-thon classCodes">Communication</classCode>
<confidentialityCode displayName="Celebrity" codingScheme="Connect-a-thon confidentialityCodes">
</XDSDocumentEntry>
In this XML I need to select nodes author, classCode and confidentialityCodes but I'm getting the text() nodes with this code:
<xsl:for-each select="node()"><!--<xsl:copy-of select="."/>-->
<!--<xsl:value-of select="local-name()"/>-->
<xsl:choose>
<xsl:when test="author">
do something
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
My result so far is this:
author<author authorRole="XDSITEST_DICOM_INSTANCE_PUBLISHER" authorPerson="XDSITEST"
authorInstitution="Some institution"/>
classCode<classCode displayName="Communication" codingScheme="Connect-a-thon classCodes">Communication</classCode>
confidentialityCode<confidentialityCode displayName="Celebrity" codingScheme="Connect-a-thon confidentialityCodes">
C</confidentialityCode>
Any hint? Thx.
EDIT
Sorry, had an error (I removed ).
Actually, why am I using the for-each is because I need the document exactly as it was except for a few nodes. In the example above the final output should look like this:
<?xml version="1.0" encoding="UTF-8"?>
<XDSDocumentEntry>
<author authorRole="XDSITEST_DICOM_INSTANCE_PUBLISHER" authorPerson="XDSITEST"
authorInstitution="Some institution"/>
<author>
<authorInstitution>
<organizationName>Some institution</organizationName>
</authorInstitution>
<authorRole>XDSITEST_DICOM_INSTANCE_PUBLISHER</authorRole>
<authorPerson>
<assigningAuthorityName>XDSITEST</assigningAuthorityName>
</authorPerson>
</author>
<classCode displayName="Communication" codingScheme="Connect-a-thon classCodes">Communication</classCode>
<confidentialityCode displayName="Celebrity" codingScheme="Connect-a-thon confidentialityCodes">
C</confidentialityCode>
</XDSDocumentEntry>
EDIT 2
I created this template as suggested by @Martin. But still how do I select the node name 'author'??
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:choose>
<xsl:when test="local-name()=author">
a
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="node()|@*"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果不知道
for-each
的上下文节点,就很难判断出了什么问题。我建议您忘记for-each
并开始编写模板,例如,如果您仍然遇到问题,请向我们展示您想要为您发布的示例输入创建什么样的输出,然后我们可以提供帮助正确的 XSLT 代码。
[编辑]
如果您想要的只是复制author元素的子节点之外的节点,那么两个模板就足够了:
It is hard to tell what goes wrong without knowing the context node of your
for-each
. I would suggest you forget aboutfor-each
and instead start writing templates e.g.If you still have problems then show us what kind of output you want to create for the sample input you posted, then we can help with the proper XSLT code.
[edit]
If all you want is copying nodes besides the child nodes of the author element then two templates suffice:
该样式表:
输出:
This stylesheet:
Output:
答案:
您没有选择。相反,您可以使用与节点(在您的情况下是
author
元素,您希望对其进行不同的处理)完全匹配的更具体的模板来覆盖身份模板。只需“按原样”复制:使用和覆盖身份规则是最基本、最强大的 XSLT 设计模式了解更多信息此处。
Answer:
You do not select. Instead, you override the identity template with a more specific template that matches exactly the node(s) (in your case the
author
element, for which you want a different processing than simply copy "as-is":Using and overriding the identity rule is the most fundamental and powerful XSLT design pattern. Read more about it here.