我需要一个XSLT文件,用输入xml中的节点子集将输入xml转换为另一个。例如,如果输入有10个节点,我需要创建大约5个节点的输出 输入
<Department diffgr:id="Department1" msdata:rowOrder="0">
<Department>10</Department>
<DepartmentDescription>BABY PRODUCTS</DepartmentDescription>
<DepartmentSeq>7</DepartmentSeq>
<InsertDateTime>2011-09-29T13:19:28.817-05:00</InsertDateTime>
</Department>
输出:
<Department diffgr:id="Department1" msdata:rowOrder="0">
<Department>10</Department>
<DepartmentDescription>BABY PRODUCTS</DepartmentDescription>
</Department>
我找到了一种方法来抑制我们不需要的节点 XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Department/DepartmentSeq"/>
<xsl:template match="Department/InsertDateTime"/>
</xsl:stylesheet>
我需要一个xslt来帮助我选择我需要的节点而不是“复制所有并过滤掉我不需要的东西”,因为每当输入架构添加更多节点时我可能不得不改变我的xslt。
更新
我发送的代码片段来自.NET Diffgram。完整的xml如下
输入:
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet>
<MessageHeader>
<MessageID>201112270242029525719b93a-5fc5-42ce-8424-10764a4497ca</MessageID>
<RequestType>Publish</RequestType>
<ListOfApplications />
<MessageType>MCH</MessageType>
</MessageHeader>
<Department diffgr:id="Department1" msdata:rowOrder="0">
<Department>10</Department>
<DepartmentDescription>BABY PRODUCTS</DepartmentDescription>
<DepartmentSeq>7</DepartmentSeq>
<InsertDateTime>2011-09-29T13:19:28.817-05:00</InsertDateTime>
<UpdateDateTime>2011-09-30T11:50:59-05:00</UpdateDateTime>
<InsertDateTimeUTC>2011-09-29T18:19:28.817-05:00</InsertDateTimeUTC>
</Department>
<Subclass diffgr:id="Subclass1" msdata:rowOrder="0" diffgr:hasChanges="modified">
<Department>10</Department>
<Category>03</Category>
<Class>010</Class>
<Subclass>03</Subclass>
<SubclassLongDescription>BABY ACCESSORIES-OTHER LD TX 1120</SubclassLongDescription>
<SubclassShortDescription>BABY ACCESSORIES-OTH</SubclassShortDescription>
</Subclass>
</NewDataSet>
<diffgr:before>
<Subclass diffgr:id="Subclass1" msdata:rowOrder="0">
<Department>10</Department>
<Category>03</Category>
<Class>010</Class>
<Subclass>03</Subclass>
<SubclassLongDescription>BABY ACCESSORIES-OTHER LD TX 1120</SubclassLongDescription>
<SubclassShortDescription>BABY ACCESSORIES-OTH</SubclassShortDescription>
</Subclass>
</diffgr:before>
</diffgr:diffgram>
提供了xslt Borodin,这是我得到的东西
<diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<NewDataSet>
<MessageHeader>
<MessageID>201112270242029525719b93a-5fc5-42ce-8424-10764a4497ca</MessageID>
<RequestType>Publish</RequestType>
<ListOfApplications />
<MessageType>MCH</MessageType>
</MessageHeader>
<Department diffgr:id="Department1" msdata:rowOrder="0">
<Department>10</Department>
<DepartmentDescription>BABY PRODUCTS</DepartmentDescription>
</Department>
<Subclass diffgr:id="Subclass1" msdata:rowOrder="0" diffgr:hasChanges="modified">
<Department>10</Department>
<Category>03</Category>
<Class>010</Class>
<Subclass>03</Subclass>
<SubclassLongDescription>BABY ACCESSORIES-OTHER LD TX 1120</SubclassLongDescription>
<SubclassShortDescription>BABY ACCESSORIES-OTH</SubclassShortDescription>
</Subclass>
</NewDataSet>
<diffgr:before>
<Subclass diffgr:id="Subclass1" msdata:rowOrder="0">
<Department>10</Department>
<Category>03</Category>
<Class>010</Class>
<Subclass>03</Subclass>
<SubclassLongDescription>BABY ACCESSORIES-OTHER LD TX 1120</SubclassLongDescription>
<SubclassShortDescription>BABY ACCESSORIES-OTH</SubclassShortDescription>
</Subclass>
</diffgr:before>
</diffgr:diffgram>
除了那些部门和部门描述标签,我不需要任何其他内容。为什么在xslt中未指定其他节点MessageHeader / subclass时会复制它们?
任何人都可以给我一个比上面更好的解决方案。添加像这样的每个节点是相当繁琐的,但如果没有其他可能的话,它会起作用。
答案 0 :(得分:2)
我建议您使用标识转换,并使用特殊规则处理<Department>
元素,以便您指定要复制的子项。这是一些示例代码。
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Department[Department]">
<xsl:copy>
<xsl:apply-templates select="@*|Department|DepartmentDescription" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我使用更新中的数据获得的输出如此
<?xml version="1.0" encoding="utf-8"?>
<diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<NewDataSet>
<Department diffgr:id="Department1" msdata:rowOrder="0">
<Department>10</Department>
<DepartmentDescription>BABY PRODUCTS</DepartmentDescription>
</Department>
</NewDataSet>
</diffgr:diffgram>
答案 1 :(得分:1)
如果您只想匹配特定节点,而不是提供排除列表,则只需输入您需要的元素名称列表
<xsl:template match="Department|DepartmentSeq|InsertDateTime|@*">
因此,给出以下XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="Department|DepartmentSeq|InsertDateTime|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" />
</xsl:stylesheet>
当应用于以下XML时(为了简化,我删除了名称空间前缀)
<Department id="Department1" rowOrder="0">
<Department>10</Department>
<DepartmentDescription>BABY PRODUCTS</DepartmentDescription>
<DepartmentSeq>7</DepartmentSeq>
<InsertDateTime>2011-09-29T13:19:28.817-05:00</InsertDateTime>
</Department>
输出以下内容。请注意,通过@ * match保留属性。
<Department id="Department1" rowOrder="0">
<Department>10</Department>
<DepartmentSeq>7</DepartmentSeq>
<InsertDateTime>2011-09-29T13:19:28.817-05:00</InsertDateTime>
</Department>
请注意使用以下模板匹配,这将排除匹配列表中不存在的所有元素。如果没有这个,默认行为是输出元素的文本值
<xsl:template match="*" />
答案 2 :(得分:0)
此解决方案最适合我的输入
<xsl:template match="diffgr:diffgram|diffgr:diffgram/NewDataSet|diffgr:diffgram/NewDataSet/Department|diffgr:diffgram/NewDataSet/Department/Department|diffgr:diffgram/NewDataSet/Department/DepartmentDescription|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" />
</xsl:stylesheet>
但是,我发现必须为层次结构中的每个节点编写匹配项非常麻烦。仍然有效,欢迎更好的解决方案!
答案 3 :(得分:0)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<xsl:output indent="yes"/><xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- shutup unwanted elements -->
<xsl:template match="MessageHeader
| Subclass
| InsertDateTime
| UpdateDateTime
| InsertDateTimeUTC
| DepartmentSeq
| diffgr:before"/>
</xsl:stylesheet>