首页 > 解决方案 > 从一个 XML 标记中获取值并使用 XSLT 放入另一个标记?

问题描述

我有一个这样的 XML

<?xml version="1.0" encoding="UTF-8"?>
<Orders>
    <Order>
        <Order_Number>8221</Order_Number>
        <Order_Date>2019-03-12 04:28</Order_Date>
        <Billing_First_Name>sdfsdff</Billing_First_Name>
        <Billing_Last_Name>zam</Billing_Last_Name>
        <Billing_Company/>
        <Billing_Address>asd aasdasd, asd</Billing_Address>
        <Billing_City>asd</Billing_City>
        <Billing_State/>
        <Billing_Postcode>5968</Billing_Postcode>
        <Billing_Country>SE</Billing_Country>
        <Billing_Email>sdfdsf@sdfsdf.se</Billing_Email>
        <Billing_Phone>454565798</Billing_Phone>
        <Shipping_First_Name>sdfsdf</Shipping_First_Name>
        <Shipping_Last_Name>sdfsdf</Shipping_Last_Name>
        <Shipping_Address>asd aasdasd, asd</Shipping_Address>
        <Shipping_City>asd</Shipping_City>
        <Shipping_State/>
        <Shipping_Postcode>5968</Shipping_Postcode>
        <Shipping_Country>XX</Shipping_Country>
        <Products>
            <Product>
                <Line_Id>1</Line_Id>
                <Name>My-Love</Name>
                <Product_Id>7978</Product_Id>
                <Product_Variation>A4</Product_Variation>
                <Variation_Id>0</Variation_Id>
                <Qty>1</Qty>
            </Product>
            <Product>
                <Line_Id>2</Line_Id>
                <Name>Other</Name>
                <Product_Id>7697</Product_Id>
                <Product_Variation>A5</Product_Variation>
                <Variation_Id>0</Variation_Id>
                <Qty>1</Qty>
            </Product>
        </Products>
    </Order>
</Orders>

我像这样用 XSLT 拆分 XML。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
  <xsl:template match="/">
  <!-- Create an output file per order from the previous query -->
      <xsl:for-each select="Orders/Order/Products/Product">
      <xsl:variable name="InputFile" select="base-uri()"/>
          <xsl:variable name="OutputFile" select="Line_Id"/>
        <xsl:result-document href="{$OutputFile}.xml" method="xml">
                    <xsl:copy-of select="current()"/>
      </xsl:result-document>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

这很好用,我得到了这样的新 XML 文件

文件_1:

<Product>
    <Line_Id>1</Line_Id>
    <Name>My-Love</Name>
    <Product_Id>7978</Product_Id>
    <Product_Variation>A4</Product_Variation>
    <Variation_Id>0</Variation_Id>
    <Qty>1</Qty>
</Product>

文件_2:

<Product>
    <Line_Id>2</Line_Id>
    <Name>Other</Name>
    <Product_Id>7697</Product_Id>
    <Product_Variation>A5</Product_Variation>
    <Variation_Id>0</Variation_Id>
    <Qty>1</Qty>
</Product>

但我的问题是,当我拆分 XML 时,我还想获取标签中的值并将其放在标签的最后,并在拆分的 XML 文件中使用空格。

拆分后的文件应该是这样的(参见名称和变体标签):

文件_1:

<Product>
    <Line_Id>1</Line_Id>
    <Name>My-Love A4</Name>
    <Product_Id>7978</Product_Id>
    <Product_Variation>A4</Product_Variation>
    <Variation_Id>0</Variation_Id>
    <Qty>1</Qty>
</Product>

文件_2:

<Product>
    <Line_Id>2</Line_Id>
    <Name>Other A5</Name>
    <Product_Id>7697</Product_Id>
    <Product_Variation>A5</Product_Variation>
    <Variation_Id>0</Variation_Id>
    <Qty>1</Qty>
</Product>  

标签: xmlxsltsplit

解决方案


而不是 using xsl:copy-of, use xsl:apply-templates,然后有一个模板匹配name来执行相关的转换,以及在所有其他节点上复制的身份模板:

试试这个 XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>

  <xsl:template match="/">
  <!-- Create an output file per order from the previous query -->
    <xsl:for-each select="Orders/Order/Products/Product">
      <xsl:variable name="InputFile" select="base-uri()"/>
      <xsl:variable name="OutputFile" select="Line_Id"/>
      <xsl:result-document href="{$OutputFile}.xml" method="xml">
        <xsl:apply-templates select="current()"/>
      </xsl:result-document>
    </xsl:for-each>
  </xsl:template>

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

  <xsl:template match="Name">
    <xsl:copy>
      <xsl:value-of select="concat(., ' ', ../Product_Variation)" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

在http://xsltfiddle.liberty-development.net/gWvjQfn上查看它的实际操作(尽管我已更改xsl:result-document为普通result-document元素,因为 xsltfiddle 将禁用 的使用xsl:result-document)。


推荐阅读