Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT:我正在尝试使用XSLT1.0根据子元素名称展平XML元素_Xml_Xslt_Transform_Flatten - Fatal编程技术网

XSLT:我正在尝试使用XSLT1.0根据子元素名称展平XML元素

XSLT:我正在尝试使用XSLT1.0根据子元素名称展平XML元素,xml,xslt,transform,flatten,Xml,Xslt,Transform,Flatten,我正在尝试使用XSLT1.0基于子元素名称展平XML元素 源XML: <Contact> <ContactPurpose> <PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText> </ContactPurpose> <ContactPurpose> <PurposeAsEnum xmlns="cds_dt">Call&l

我正在尝试使用XSLT1.0基于子元素名称展平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>

O
呼叫
逻辑是:

如果子元素名称为“purposasplaintext”,则 为目标中的其他设置“O”

ELSEIF子元素名称为“PurposeAsEnum”,则 将源值复制到目标

编辑1:我可以更清楚地说,因为没有一个解决方案能压平xml,请参阅修订后的source和dest 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>

呼叫
呼叫

O

更新:修改了答案以适应更改的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

这可以通过简单而简短的方式完成(无显式条件)

<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>
<Contact>
   <ContactPurpose>0</ContactPurpose>
   <ContactPurpose>Call</ContactPurpose>
</Contact>
<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>
<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
应用于以下XML文档时(扩展为包含两种感兴趣的情况):


呼叫
呼叫
生成所需的正确结果

<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>
<Contact>
   <ContactPurpose>0</ContactPurpose>
   <ContactPurpose>Call</ContactPurpose>
</Contact>
<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>
<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
呼叫
说明

<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>
<Contact>
   <ContactPurpose>0</ContactPurpose>
   <ContactPurpose>Call</ContactPurpose>
</Contact>
<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>
<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>
覆盖并适当使用模板/匹配模式

更新:OP已修改其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" 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>
<Contact>
   <ContactPurpose>0</ContactPurpose>
   <ContactPurpose>Call</ContactPurpose>
</Contact>
<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>
<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
将此转换应用于新的XML文档(最接近上面的文档)时,将生成所需的正确新结果

<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>
<Contact>
   <ContactPurpose>0</ContactPurpose>
   <ContactPurpose>Call</ContactPurpose>
</Contact>
<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>
<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
呼叫

如果您为子元素为“PurposeAsEnum”的情况提供输入和输出示例,将非常有用。请参阅修订后的源和目标XML。所有解决方案都输出相同的XML,但忘记了展平并删除子元素名称。此注释中的XML解决方案结果与我上面所需的输出不同。请致电@user610064:感谢您的编辑。您可能已经注意到,我的答案使用的正是您提供的XML文档ide进行了最新的编辑,并生成了想要的结果。@Dimitre Novatchev:出于某种原因,当我运行XSL转换时,它没有应用它,我得到了一个正常的副本。你确定我和Dimitre的解决方案没有展平/删除PurposeSplaintext元素吗?我想知道你的输入XML是否与你发布的不完全一样——也许你已经这样做了请告诉我其中的其他名称空间,或不同的名称空间URI?这不会产生想要的结果。当我第一次看到这个答案时,我认为它是错误的,但随后我得出结论,它产生的结果与原始的、模棱两可的问题是一致的。我想我应该让OP来决定它是否匹配他真正想要的输出ed.是不是因为我有两个XSD文件,但只引用XSLT中的“sub”XSD而没有应用转换?(参见上面的注释)。还是C#XslCompiledTransform是一个有缺陷的类/XSL解析器?@user610064:我总是在发布代码之前测试代码。使用任何兼容的XSLT1.0处理器(包括.NET XslCompiledTransform)应用转换--在提供的XML文件上,您会得到想要的结果。很可能您有不同的XML文档或修改了转换,或两者都有。请参阅已编辑的问题和随附的新注释:命名空间。我完全按照您发布的内容复制了XSL,但没有成功地使用它或使用另一个命名空间“CD”.奇怪…@Dimitri Novatchev:您的解决方案在免费的在线工具上确实有效(但不适用于.NET 4.0 XslCompiledTransform)。您的解决方案不适用于与我修订的XML相同的免费在线工具。我使用:@Dimitri Novatchev:Correction您的解决方案适用于原始XML片段。谢谢。您的解决方案适用于免费在线工具(但不适用于.NET 4.0 XslCompiledTransform)。您的解决方案不适用于与我修订的XML相同的免费在线工具。我使用了:xslt.online-toolz.com/tools/xslt-transformation.php更正您的解决方案不适用于原始XML代码段。谢谢。@user610064:我想您不应该因为不知道您最初发布的代码段与实际的XML代码段不兼容而受到责备您正在使用的文档。代码段中的元素实际上与实际文档中的元素不同,因为它们属于不同的命名空间。为了避免将来出现这种混淆,您需要(a)理解XML命名空间,或者(b)在寻求帮助时传达所有可能相关的细节,以避免遗漏关键细节。@user610064:(b)确实不切实际。我强烈建议(a)。正如驾驶手动变速器汽车而不了解离合器的成本很高一样(对你和技工来说),使用XML名称空间也一样,但不知道它们是如何工作的。我记得几年前学习了手动传输,我擅长加速,但在每个角落都停滞不前……)