2012-03-05 121 views
1

正在尝试使用XSLT 1.0XSLT:我想基于使用XSLT 1.0

源XML扁平化基础上的子元素名称的XML元素的子元素的名字拼合XML元素:

<Contact> 
    <ContactPurpose> 
    <PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText> 
    </ContactPurpose> 
    <ContactPurpose> 
    <PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum> 
    </ContactPurpose> 
</Contact> 

应变换为下面的XML:

<Contact> 
    <ContactPurpose>O</ContactPurpose> 
    <ContactPurpose>Call</ContactPurpose> 
</Contact> 

的逻辑是:

如果子元素名称是“PurposeAsPlainText“目的地THEN 集‘O’为其他

ELSEIF子元素名称是‘PurposeAsEnum’THEN 源值复制到目标

编辑1:我可能会更清楚,因为没有任何解决方案将XML解压缩,请参阅修订的源和目标XML。

编辑2:这是我测试的XML。下面的两个转换解决方案实际上可以在我的原始xml上工作,但不是我使用.NET 4.0 XslCompiledTransform进行测试的修订后的xml。或者我应该提出一个新问题?

<MyDS xmlns="cds" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <PatientRecord> 
    <Demographics> 
     <Contact> 
     <ContactPurpose> 
      <PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText> 
     </ContactPurpose> 
     <ContactPurpose> 
      <PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum> 
     </ContactPurpose> 
     </Contact> 
    </Demographics> 
    </PatientRecord> 
</MyDS> 
+0

如果您在子元素为“PurposeAsEnum”的情况下给出示例输入和输出将会很有帮助。 – LarsH 2012-03-05 20:43:16

+0

请参阅修订后的源和目标XML。所有解决方案都输出相同的XML,但忘记了拼合并删除子元素名称。这个评论中的xml解决方案与我上面希望的输出不一样。 Call user610064 2012-03-06 13:49:39

+0

@ user610064:感谢您的编辑。您可能已经注意到,我的答案完全使用您在最新编辑中提供的XML文档,并生成完全想要的结果。 – 2012-03-06 14:31:38

回答

1

这可以在一个简单的和短期的方式来完成(没有明确的条件语句)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:x="cds_dt" exclude-result-prefixes="x"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="ContactPurpose/x:PurposeAsPlainText/text()">0</xsl:template> 

<xsl:template match="ContactPurpose/*"><xsl:apply-templates/></xsl:template> 
</xsl:stylesheet> 

当施加到下面的XML文档(扩展到encorporate感兴趣这两种情况下):

<Contact> 
    <ContactPurpose> 
     <PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText> 
    </ContactPurpose> 
    <ContactPurpose> 
     <PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum> 
    </ContactPurpose> 
</Contact> 

产生想要的,正确的结果

<Contact> 
    <ContactPurpose>0</ContactPurpose> 
    <ContactPurpose>Call</ContactPurpose> 
</Contact> 

说明

重写identity rule和适当使用的模板/匹配模式。

更新:该任择议定书已经修改了他的XML文档,这是现在在默认命名空间:

<MyDS xmlns="cds" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <PatientRecord> 
     <Demographics> 
      <Contact> 
       <ContactPurpose> 
        <PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText> 
       </ContactPurpose> 
       <ContactPurpose> 
        <PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum> 
       </ContactPurpose> 
      </Contact> 
     </Demographics> 
    </PatientRecord> 
</MyDS> 

因此,这里是产生想要的结果略微修改后的转换:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:x="cds_dt" xmlns:c="cds" exclude-result-prefixes="c x"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="c:ContactPurpose/x:PurposeAsPlainText/text()">0</xsl:template> 

    <xsl:template match="c:ContactPurpose/*"><xsl:apply-templates/></xsl:template> 
</xsl:stylesheet> 

将此转换应用于新XML文档(最接近的上面)时,新的想要的正确结果是produc编号

<MyDS xmlns="cds" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <PatientRecord> 
     <Demographics> 
     <Contact> 
      <ContactPurpose>0</ContactPurpose> 
      <ContactPurpose>Call</ContactPurpose> 
     </Contact> 
     </Demographics> 
    </PatientRecord> 
</MyDS> 
+0

是不是应用转换,因为我有两个XSD文件,但只引用XSLT中的'sub'XSD? (见上面的评论)。或者是C#XslCompiled转换一个错误的类/ XSL解析器? – user610064 2012-03-07 18:20:09

+0

@ user610064:我在发布之前总是测试我的代码。使用任何兼容的XSLT 1.0处理器(包括.NET XslCompiledTransform)对所提供的XML文件应用转换,并获得所需的结果。很可能你有一个不同的XML文档,或者有更改的转换,或两者兼而有之。 – 2012-03-07 19:13:43

+0

请参阅编辑的问题以及随附的新评论re:命名空间。我完全按照您发布的内容复制了您的XSL,但没有逐字或使用其他名称空间“cds”取得成功。奇怪... – user610064 2012-03-08 12:52:14

1
<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cds="cds_dt" exclude-result-prefixes="cds"> 
<!-- identity transform - just copy things that don't have a better rule --> 
<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

<!- a rule for what needs changing --> 
<xsl:template match="ContactPurpose[cds:PurposeAsPlainText] "> 
    <ContactPurpose>O</ContactPurpose> 
</xsl:template> 
</xsl:stylesheet> 
+0

这不会产生想要的结果。 – 2012-03-06 14:33:04

+0

当我第一次看到这个答案时,我认为这是错误的,但后来我得出结论,它产生的结果与原始的,模糊的问题是一致的。我想我会把它留给OP来决定它是否与他真正想要的输出相匹配。 – LarsH 2012-03-08 20:39:00

1

更新:修改了答案,以适应变化的XML源文档。

的描述不是很清楚,但这里是我认为你正在试图做的:

<xsl:stylesheet version="1.0" xmlns:cds_dt="cds_dt" xmlns:cds="cds" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<!-- Identity transform --> 
<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="cds:ContactPurpose"> 
    <xsl:copy> 
     <xsl:choose> 
     <!-- when there is a child element PurposeAsPlainText 
      in the cds_dt namespace: --> 
     <xsl:when test="cds_dt:PurposeAsPlainText">0</xsl:when> 
     <!-- I'm guessing that PurposeAsEnum is also supposed to be 
      in the cds_dt namespace. --> 
     <xsl:otherwise> 
      <xsl:value-of select="cds_dt:PurposeAsEnum" /> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
+0

您的解决方案可以在免费的在线工具上运行(但不适用于.NET 4.0 XslCompiledTransform)。您的解决方案不适用于使用修订后的XML的免费在线工具。我使用:xslt.online-toolz.com/tools/xslt-transformation.php – user610064 2012-03-08 13:13:02

+0

更正您的解决方案在原始XML片段中的工作。谢谢。 – user610064 2012-03-08 13:49:55

+0

@ user610064:我想你不应该因为不知道你最初发布的代码片段与你正在使用的实际XML文档不兼容。代码片段中的元素实际上是*不同于实际文档中的元素,因为它们属于不同的名称空间。为避免将来出现混淆,您需要(a)了解XML名称空间,或(b)在寻求帮助时传达所有可能相关的详细信息,以避免忽略此时发生的关键细节。 – LarsH 2012-03-08 16:25:06