Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.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
从xsl转换创建多个xml,并将数据放入这些xml';基于源xml的标记属性_Xml_Xslt_Xpath_Xslt 2.0 - Fatal编程技术网

从xsl转换创建多个xml,并将数据放入这些xml';基于源xml的标记属性

从xsl转换创建多个xml,并将数据放入这些xml';基于源xml的标记属性,xml,xslt,xpath,xslt-2.0,Xml,Xslt,Xpath,Xslt 2.0,我正在尝试使用XSL2.0基于语言名称创建不同的xml文件。在我的输入xml中,这里只有两种语言,“en”和“es” 所有基于“en”的人员都将访问en.xml并 所有基于“es”的人员都将转到es.xml并 所有同时拥有“en”和“es”的人都必须同时访问en.xml和es.xml 我的输入XML: 源xml是关于人员列表、地址和语言的 <persons> <person name="Alice"> <Addresses>

我正在尝试使用XSL2.0基于语言名称创建不同的xml文件。在我的输入xml中,这里只有两种语言,“en”和“es”

  • 所有基于“en”的人员都将访问en.xml并
  • 所有基于“es”的人员都将转到es.xml并
  • 所有同时拥有“en”和“es”的人都必须同时访问en.xml和es.xml
  • 我的输入XML: 源xml是关于人员列表、地址和语言的

    <persons>
        <person name="Alice">
            <Addresses>
                <Address type ="personal">
                    <language name = "en">
                    </language>
                </Address>
                <Address type ="business">
                    <language name = "en">
                    </language>
                </Address>
            </Addresses>
        </person>
        <person name="Bob">
            <Addresses>
                <Address type ="personal">
                    <language name = "es">
                    </language>
                </Address>
                <Address type ="business">
                    <language name = "es">
                    </language>
                </Address>
            </Addresses>
        </person>
        <person name="Stacy">
            <Addresses>
                <Address type ="personal">
                    <language name = "en">
                    </language>
                </Address>
                <Address type ="business">
                    <language name = "es">
                    </language>
                </Address>
            </Addresses>
        </person>
    </persons>
    
    
    
    以下是一个XSLT 2.0示例:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:output indent="yes"/>
    
    <xsl:template match="@* | node()">
      <xsl:copy>
        <xsl:apply-templates select="@* , node()"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="persons">
      <xsl:for-each-group select="person" group-by="Addresses/Address/language/@name">
        <xsl:result-document href="{current-grouping-key()}.xml">
          <xsl:apply-templates select="current-group()"/>
        </xsl:result-document>
      </xsl:for-each-group>
    </xsl:template>
    
    <xsl:template match="person/Addresses">
      <xsl:if test="Address/language/@name = current-grouping-key()">
        <xsl:next-match/>
      </xsl:if>
    </xsl:template>
    
    </xsl:stylesheet>
    

    以下是XSLT 2.0示例:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:output indent="yes"/>
    
    <xsl:template match="@* | node()">
      <xsl:copy>
        <xsl:apply-templates select="@* , node()"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="persons">
      <xsl:for-each-group select="person" group-by="Addresses/Address/language/@name">
        <xsl:result-document href="{current-grouping-key()}.xml">
          <xsl:apply-templates select="current-group()"/>
        </xsl:result-document>
      </xsl:for-each-group>
    </xsl:template>
    
    <xsl:template match="person/Addresses">
      <xsl:if test="Address/language/@name = current-grouping-key()">
        <xsl:next-match/>
      </xsl:if>
    </xsl:template>
    
    </xsl:stylesheet>
    

    小问题:与其将语言元素作为子节点放在Address下,不如将其作为Address属性。我无法做到这一点。。由于源xml不能以任何方式更改,因为它是从不同的系统生成的…对于解决方案,我尝试了大量循环,但仍然没有帮助获得正确的输出..参考@MartinHonnen答案,可能更多您想要的内容。小问题:与其将语言元素作为子节点放在Address下,把它作为地址属性。我不能这么做。。由于源xml不能以任何方式更改,因为它是从不同的系统生成的…对于解决方案,我尝试了很多循环,但仍然没有帮助获得正确的输出..参考@MartinHonnen答案,可能更多您想要的内容。Martin-感谢您的输入。但是,在转换之后,es.xml将不会有地址type=“personal”和语言name=“en”,它们也应该存在。介于两者之间的是。。。。。所有数据都应该像源xml一样存在于es.xml中。看起来我的第一次尝试过滤了太多的数据,mzjn已经发布了一个更正的样式表,我也将在编辑中更正我的代码。Martin-感谢您的输入。但是,在转换之后,es.xml将不会有地址type=“personal”和语言name=“en”,它们也应该存在。介于两者之间的是。。。。。所有数据都应该在es.xml中,就像在源xml中一样。看起来我的第一次尝试过滤了太多的数据,mzjn已经发布了一个更正的样式表,我也将在编辑中更正我的代码。
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      version="2.0">
    
    <xsl:output method="xml" indent="yes" name="xml"/>
    
    <xsl:template match="/">
        <xsl:for-each select="//persons">
           <xsl:variable name="filename"
                 select="concat('allpersons/',//persons/person/Addresses/Address/language/@name,'.xml')" />
           <xsl:value-of select="$filename" />  <!-- Creating  -->
           <xsl:result-document href="{$filename}" format="xml">
                 <xsl:value-of select="."/>
           </xsl:result-document>
         </xsl:for-each>
    </xsl:template>
    </xsl:stylesheet>
    
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:output indent="yes"/>
    
    <xsl:template match="@* | node()">
      <xsl:copy>
        <xsl:apply-templates select="@* , node()"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="persons">
      <xsl:for-each-group select="person" group-by="Addresses/Address/language/@name">
        <xsl:result-document href="{current-grouping-key()}.xml">
          <xsl:apply-templates select="current-group()"/>
        </xsl:result-document>
      </xsl:for-each-group>
    </xsl:template>
    
    <xsl:template match="person/Addresses">
      <xsl:if test="Address/language/@name = current-grouping-key()">
        <xsl:next-match/>
      </xsl:if>
    </xsl:template>
    
    </xsl:stylesheet>
    
    <xsl:template match="persons">
      <xsl:for-each-group select="person" group-by="Addresses/Address/language/@name">
        <xsl:result-document href="{current-grouping-key()}.xml">
          <persons>
            <xsl:apply-templates select="current-group()"/>
          </persons>
        </xsl:result-document>
      </xsl:for-each-group>
    </xsl:template>