【问题标题】:Reorder xml, first the text nodes, then the nodes with childs [duplicate]重新排序xml,首先是文本节点,然后是带有子节点的节点[重复]
【发布时间】:2012-06-20 16:23:30
【问题描述】:

可能重复:
Rebuild magento XML with nodes related to each other, closer together with a transform.

这是一个双重帖子,但使用当前标签我没有得到回复。我会更新其他帖子或删除它。

我从 Magento 那里得到了这个,开发人员不能轻易地将它更改为“之后”示例。我的解析器在解析这个时遇到了一些问题,所以我的问题是。我可以使用 xsl 样式表将其转换为“之后”示例,其中 nodea 到 nodeh 更接近彼此,因此更具可读性。

这将节省我大量研究解析器的时间。

之前:

    <Envelope encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<Body>
    <salesOrderInfoResponse>
        <result type="ns1:salesOrderEntity">
            <nodec>value</nodec>
            <noded>value</noded>
            <shipping_address type="ns1:salesOrderAddressEntity">
                <parent_id type="xsd:string">762</parent_id>
                <address_type type="xsd:string">shipping</address_type>
                <firstname type="xsd:string">K</firstname>
                <lastname type="xsd:string">Jansen</lastname>
            </shipping_address>
            <billing_address type="ns1:salesOrderAddressEntity">
                <parent_id type="xsd:string">762</parent_id>
                <address_type type="xsd:string">billing</address_type>
                <firstname type="xsd:string">K</firstname>
                <lastname type="xsd:string">Jansen</lastname>
            </billing_address>
            <items arrayType="ns1:salesOrderItemEntity[4]" type="ns1:salesOrderItemEntityArray">
                <item type="ns1:salesOrderItemEntity">
                    <item_id type="xsd:string">3105</item_id>
                </item>
                <item type="ns1:salesOrderItemEntity">
                    <item_id type="xsd:string">3106</item_id>
                </item>
                <item type="ns1:salesOrderItemEntity">
                    <item_id type="xsd:string">3107</item_id>
                </item>
                <item type="ns1:salesOrderItemEntity">
                    <item_id type="xsd:string">3108</item_id>
                </item>
            </items>
            <payment type="ns1:salesOrderPaymentEntity">
                <parent_id type="xsd:string">762</parent_id>
                <cc_last4 type="xsd:string"></cc_last4>
            </payment>
            <nodea>value</nodea>
            <nodeb>value</nodeb>
            <nodee>value</nodee>
            <nodef>value</nodef>
            <nodeg>value</nodeg>
            <nodeh>value</nodeh>
        </result>
    </salesOrderInfoResponse>
</Body>

之后:

<Envelope encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<Body>
    <salesOrderInfoResponse>
        <result type="ns1:salesOrderEntity">
            <nodea>value</nodea>
            <nodeb>value</nodeb>
            <nodec>value</nodec>
            <noded>value</noded>
            <nodee>value</nodee>
            <nodef>value</nodef>
            <nodeg>value</nodeg>
            <nodeh>value</nodeh>
            <shipping_address type="ns1:salesOrderAddressEntity">
                <parent_id type="xsd:string">762</parent_id>
                <address_type type="xsd:string">shipping</address_type>
                <firstname type="xsd:string">K</firstname>
                <lastname type="xsd:string">Jansen</lastname>
            </shipping_address>
            <billing_address type="ns1:salesOrderAddressEntity">
                <parent_id type="xsd:string">762</parent_id>
                <address_type type="xsd:string">billing</address_type>
                <firstname type="xsd:string">K</firstname>
                <lastname type="xsd:string">Jansen</lastname>
            </billing_address>
            <items arrayType="ns1:salesOrderItemEntity[4]" type="ns1:salesOrderItemEntityArray">
                <item type="ns1:salesOrderItemEntity">
                    <item_id type="xsd:string">3105</item_id>
                </item>
                <item type="ns1:salesOrderItemEntity">
                    <item_id type="xsd:string">3106</item_id>
                </item>
                <item type="ns1:salesOrderItemEntity">
                    <item_id type="xsd:string">3107</item_id>
                </item>
                <item type="ns1:salesOrderItemEntity">
                    <item_id type="xsd:string">3108</item_id>
                </item>
            </items>
            <payment type="ns1:salesOrderPaymentEntity">
                <parent_id type="xsd:string">762</parent_id>
                <cc_last4 type="xsd:string"></cc_last4>
            </payment>
        </result>
    </salesOrderInfoResponse>
</Body>

我添加了一个 xslt 建议并对其进行了一些修改,它的接缝正在工作:

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


<xsl:template match="result"> 
    <xsl:copy> 
        <xsl:apply-templates select="@*" /> 
        <xsl:apply-templates select="*[    starts-with(local-name(),'node') ]" /> 
        <xsl:apply-templates select="*[not(starts-with(local-name(),'node'))]|processing-instruction()|comment()" /> 
    </xsl:copy> 
</xsl:template> 

我知道有:

  <salesOrderInfoResponse> 

     <result type="ns1:salesOrderEntity">
        <nodec>value</nodec>
        <noded>value</noded>
        <nodea>value</nodea>
        <nodeb>value</nodeb>
        <nodee>value</nodee>
        <nodef>value</nodef>
        <nodeg>value</nodeg>
        <nodeh>value</nodeh>
        <shipping_address type="ns1:salesOrderAddressEntity"> 

           <parent_id type="xsd:string">762</parent_id> 

           <address_type type="xsd:string">shipping</address_type> 

           <firstname type="xsd:string">K</firstname> 

           <lastname type="xsd:string">Jansen</lastname> 

        </shipping_address>
        <billing_address type="ns1:salesOrderAddressEntity"> 

           <parent_id type="xsd:string">762</parent_id> 

           <address_type type="xsd:string">billing</address_type> 

           <firstname type="xsd:string">K</firstname> 

           <lastname type="xsd:string">Jansen</lastname> 

        </billing_address>
        <items arrayType="ns1:salesOrderItemEntity[4]" type="ns1:salesOrderItemEntityArray"> 

           <item type="ns1:salesOrderItemEntity"> 

              <item_id type="xsd:string">3105</item_id> 

           </item> 

           <item type="ns1:salesOrderItemEntity"> 

              <item_id type="xsd:string">3106</item_id> 

           </item> 

           <item type="ns1:salesOrderItemEntity"> 

              <item_id type="xsd:string">3107</item_id> 

           </item> 

           <item type="ns1:salesOrderItemEntity"> 

              <item_id type="xsd:string">3108</item_id> 

           </item> 

        </items>
        <payment type="ns1:salesOrderPaymentEntity"> 

           <parent_id type="xsd:string">762</parent_id> 

           <cc_last4 type="xsd:string"/> 

        </payment>
     </result> 

  </salesOrderInfoResponse> 

这几乎是正确的!我不明白额外间距来自哪里,但我在正确的轨道上。

用真实数据进一步测试我没有看到顶部的文本节点。在上面的例子中,我猜是因为'node'命令。我创建了这个示例并用作文本节点、nodea、nodeb 等,但在现实生活中它们被称为 orderid、name、数量。

查看带有子节点的 xml 节点,我可以看到它们都有一个属性类型,其值以“ns1:...”开头

【问题讨论】:

  • 是的,您可以使用 xslt 对其进行转换。您有哪些 XSLT 引擎选项?
  • 我在这里阅读了很多帖子以找到解决方案,我猜你的意思是 1.0 或 2.0。我不确定,我使用的是 xml dom 6.0
  • 您正在运行什么 XSLT 引擎?它是服务器端还是客户端(浏览器)?您使用的是哪个版本的 XSLT?
  • 我不确定。我在我的 pascal 程序中使用 msxml6 作为自动化。
  • 我怎样才能重新打开它。我没有答案,我已经测试了给定的答案并更新了问题...

标签: xml xslt xsd


【解决方案1】:

试试这个 XSLT 1.0 样式表 ...

<?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="result">
 <xsl:copy>
   <xsl:apply-templates select="@*" />
   <xsl:apply-templates select="*[not(starts-with(local-name(),'node'))]|processing-instruction()|comment()" />
   <xsl:apply-templates select="*[    starts-with(local-name(),'node') ]" />
 </xsl:copy>
</xsl:template>

</xsl:stylesheet>

或者,您可以更改...的模板

<xsl:template match="result">
 <xsl:copy>
   <xsl:apply-templates select="@*" />
   <xsl:apply-templates select="node()">
     <xsl:sort select="starts-with(local-name(),'node') and self::*" data-type="number" />
  </xsl:apply-templates>
 </xsl:copy>
</xsl:template>

如果您需要 XSLT 2.0,请告诉我们,因为 XSLT 2.0 会有更简洁的解决方案。

【讨论】:

  • 感谢您的帮助。我真的不知道我是否可以使用 XSLT 2.0,但已经更新了你 xslt 的问题。
  • @user324365 请您接受其中一个答案。
  • 我已经更新了这个问题,我不能接受它作为答案,因为它固定在“节点”文本上。
  • 如果是这种情况,您的问题确实需要澄清。目前尚不清楚确定哪些节点位于底部的决定因素是什么。如果您再次发布此问题,请确保您对规则非常准确,并包含几个测试用例。
  • 很抱歉,该主题已被某人关闭。就像它说的那样;首先是文本节点/元素,然后是带有子节点的节点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
相关资源
最近更新 更多