我需要遍历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中,我需要选择节点作者, 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>
任何提示? THX。
抱歉,有错误(我已删除)。
实际上,为什么我使用 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>
我按照@Martin的建议创建了这个模板。但是我如何选择节点名称'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>
答案 0 :(得分:2)
如果不了解for-each
的上下文节点,很难说出现了什么问题。我建议你忘记for-each
,而是开始编写模板,例如
<xsl:template match="XDSDocumentEntry/*">
<!-- output here what you want to output for child elements of XDSDocumentEntry -->
</xsl:template>
<xsl:template match="XDSDocumentEntry/author">
<!-- put needed special treatement of author element here -->
</xsl:template>
如果您仍有问题,请告诉我们您要为您发布的示例输入创建哪种输出,然后我们可以帮助您使用正确的XSLT代码。
[编辑] 如果你想要的只是复制author元素的子节点之外的节点,那么两个模板就足够了:
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="XDSDocumentEntry/author">
<xsl:copy>
<xsl:apply-templates select="@*"/>
</xsl:copy>
</xsl:template>
答案 1 :(得分:2)
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="author/node()"/>
<xsl:template match="author">
<xsl:call-template name="identity"/>
<xsl:copy>
<xsl:apply-templates select="@*" mode="element"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*" mode="element">
<xsl:element name="{name()}">
<xsl:apply-templates select="." mode="value"/>
</xsl:element>
</xsl:template>
<xsl:template match="author/@authorPerson" mode="value">
<assigningAuthorityName>
<xsl:value-of select="."/>
</assigningAuthorityName>
</xsl:template>
</xsl:stylesheet>
输出:
<XDSDocumentEntry id="DOC01">
<author authorRole="XDSITEST_DICOM_INSTANCE_PUBLISHER" authorPerson="XDSITEST"></author>
<author>
<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"></confidentialityCode>
</XDSDocumentEntry>
答案 2 :(得分:1)
我按照建议创建了这个模板 由@Martin。但我仍然如何选择 节点名称'author'??
回答:
你不选择。相反,您覆盖身份模板,使用更具体的模板,该模板与节点完全匹配(在您的情况下为author
元素,您希望进行与简单复制不同的处理“原样“:
<xsl:template match="author">
<!-- Put your specific code here -->
</xsl:template>
使用和覆盖标识规则是最基本和最强大的XSLT设计模式。阅读更多相关信息here。