Xml XSLT 1.0两个不同节点之间的所有节点

Xml XSLT 1.0两个不同节点之间的所有节点,xml,xslt,xpath,Xml,Xslt,Xpath,我有一个XML节点列表,需要将其转换为某种结构化数据,但我遇到了一些麻烦 我对如何获取标题(Customer、User)下的子数据有很好的了解,但我确实很难在两个不同名称的节点(包括这些节点)之间进行选择。我真的在寻找XPath,它允许选择这些区域 因此,对于Customer节点,我需要在CustomerName和UserName之前的节点之间进行选择(实际数据中有更多的节点)。然后,对于每个用户(其中有一个未知的数量),我需要在下一个用户名之前获得用户名和节点之间的数据,同样,在实际数据中不仅

我有一个XML节点列表,需要将其转换为某种结构化数据,但我遇到了一些麻烦

我对如何获取标题(Customer、User)下的子数据有很好的了解,但我确实很难在两个不同名称的节点(包括这些节点)之间进行选择。我真的在寻找XPath,它允许选择这些区域

因此,对于Customer节点,我需要在CustomerName和UserName之前的节点之间进行选择(实际数据中有更多的节点)。然后,对于每个用户(其中有一个未知的数量),我需要在下一个用户名之前获得用户名和节点之间的数据,同样,在实际数据中不仅仅有两个节点

我曾尝试使用前兄弟姐妹、后兄弟姐妹和计数的组合,但我就是无法让正确的组合起作用。任何指向正确方向的指针都会大有帮助

我更喜欢XSLT1.0,但我可以使用2.0

示例数据:

<Data>
  <CustomerName>
    <Name>ABCCompany</Name>
  </CustomerName>
  <CustomerAddress>
    <City>AnyCity</City>
    <State>AnyState</State>
  </CustomerAddress>
  <UserName>
    <Name>Betty<Name>
  </UserName>
  <UserAddress>
    <City>AnyCity</City>
    <State>AnyState</State>
  </UserAddress>
  <UserName>
    <Name>Johnny</Name>
  </UserName>
  <UserAddress>
    <City>AnyCity</City>
    <State>AnyState</State>
  </UserAddress>
</Data>

ABC公司
任何城市
任何州
贝蒂
任何城市
任何州
约翰尼
任何城市
任何州
期望输出:

<Data>
  <Customer>
    <CustomerName>
      <Name>ABCCompany</Name>
    </CustomerName>
    <CustomerAddress>
    <City>AnyCity</City>
    <State>AnyState</State>
    </CustomerAddress>
  </Customer>
  <Users>
    <User>
      <UserName>
        <Name>Betty</Name>
      </UserName>
      <UserAddress>
    <City>AnyCity</City>
    <State>AnyState</State>
      </UserAddress>
    </User>
    <User>
      <UserName>
        <Name>Johnny</Name>
      </UserName>
      <UserAddress>
    <City>AnyCity</City>
    <State>AnyState</State>
      </UserAddress>
    </User>
  </Users>
</Data>

ABC公司
任何城市
任何州
贝蒂
任何城市
任何州
约翰尼
任何城市
任何州

这里是一个粗略的原型,说明了如何在XSLT 2.0中实现这一点:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/Data">
    <xsl:copy>
        <xsl:for-each-group select="*" group-starting-with="CustomerName|UserName">
            <group type="{name(current-group()[1])}">
                <xsl:copy-of select="current-group()" />
            </group>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入(针对良好格式进行了更正!),结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<Data>
   <group type="CustomerName">
      <CustomerName>
         <Name>ABCCompany</Name>
      </CustomerName>
      <CustomerAddress>
         <City>AnyCity</City>
         <State>AnyState</State>
      </CustomerAddress>
   </group>
   <group type="UserName">
      <UserName>
         <Name>Betty</Name>
      </UserName>
      <UserAddress>
         <City>AnyCity</City>
         <State>AnyState</State>
      </UserAddress>
   </group>
   <group type="UserName">
      <UserName>
         <Name>Johnny</Name>
      </UserName>
      <UserAddress>
         <City>AnyCity</City>
         <State>AnyState</State>
      </UserAddress>
   </group>
</Data>

ABC公司
任何城市
任何州
贝蒂
任何城市
任何州
约翰尼
任何城市
任何州
您可以使用表达式
name(current-group()[1])
为每个组选择适当的元素包装器



演示:

这里是一个粗略的原型,介绍了如何在XSLT2.0中实现这一点:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/Data">
    <xsl:copy>
        <xsl:for-each-group select="*" group-starting-with="CustomerName|UserName">
            <group type="{name(current-group()[1])}">
                <xsl:copy-of select="current-group()" />
            </group>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入(针对良好格式进行了更正!),结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<Data>
   <group type="CustomerName">
      <CustomerName>
         <Name>ABCCompany</Name>
      </CustomerName>
      <CustomerAddress>
         <City>AnyCity</City>
         <State>AnyState</State>
      </CustomerAddress>
   </group>
   <group type="UserName">
      <UserName>
         <Name>Betty</Name>
      </UserName>
      <UserAddress>
         <City>AnyCity</City>
         <State>AnyState</State>
      </UserAddress>
   </group>
   <group type="UserName">
      <UserName>
         <Name>Johnny</Name>
      </UserName>
      <UserAddress>
         <City>AnyCity</City>
         <State>AnyState</State>
      </UserAddress>
   </group>
</Data>

ABC公司
任何城市
任何州
贝蒂
任何城市
任何州
约翰尼
任何城市
任何州
您可以使用表达式
name(current-group()[1])
为每个组选择适当的元素包装器



演示:

这与--p.S.类似。请提供一个可用的示例
1
不是有效的元素名称。1不重要,我只是将它们用作占位符。我会看看这个链接的问题是否对我有效。这对我们中任何想使用您的代码进行测试以便为您提供答案的人都很重要。请节省我们的时间。我更新了XML。链接问题用于每个组,如果所有节点都有相同的子节点,则该问题似乎有效,但它们不会,并且我不知道需要分隔的节点之间有哪些节点。请尝试
。这类似于:--P.S。请提供一个可用的示例
1
不是有效的元素名称。1不重要,我只是将它们用作占位符。我会看看这个链接的问题是否对我有效。这对我们中任何想使用您的代码进行测试以便为您提供答案的人都很重要。请节省我们的时间。我更新了XML。链接问题用于每个组,如果所有节点都有相同的子节点,则该问题似乎有效,但它们不会,并且我不知道需要分隔的节点之间有哪些节点。请尝试