【问题标题】:XSLT transform to tree XML structure via attributeXSLT 通过属性转换为树 XML 结构
【发布时间】:2015-07-21 16:36:34
【问题描述】:

我有一些具有以下平面结构的 XML 文件:

<managedObject class="MGW" version="U5.0EP2" distName="PLMN-PLMN/MGW-219454" id="192614000001726941">
  <list name="mgwOptions">
    <p>M3UA Interface (No 50035)</p>
  </list>
  <p name="name">MGW_A</p>
</managedObject>
<managedObject class="ATM" version="U5.0EP2" distName="PLMN-PLMN/MGW-219454/ATM-1" id="192614000003145148">
  <p name="lastSuccessfulUploadTimeStamp">21/07/15 01:32:40</p>
</managedObject>
<managedObject class="IFPG" version="A10TOP" distName="PLMN-PLMN/MGW-219454/ATM-1/IFPG-0" id="192614000003415034">
  <p name="prSectionSdhExchangeTerminalIndex">1</p>
  <p name="protectionSwitchingMode">REV</p>
  <p name="protocolVariant">MSP</p>
  <p name="switchingDirection">WO</p>
  <p name="waitToRestoreTime">300</p>
  <p name="woSectionSdhExchangeTerminalIndex">0</p>
</managedObject>
<managedObject class="IFPG" version="A10TOP" distName="PLMN-PLMN/MGW-219454/ATM-1/IFPG-1" id="192614000003415035">
  <p name="prSectionSdhExchangeTerminalIndex">3</p>
  <p name="protectionSwitchingMode">REV</p>
  <p name="protocolVariant">MSP</p>
  <p name="switchingDirection">WO</p>
  <p name="waitToRestoreTime">300</p>
  <p name="woSectionSdhExchangeTerminalIndex">2</p>
</managedObject>

我想根据 managedObjects 元素的 distNameclass 属性使用 XSL 将其转换为更树状的结构。比如:

<?xml version="1.0"?>
<managedObject class="MGW" version="U5.0EP2" distName="PLMN-PLMN/MGW-219454" id="192614000001726941">
  <list name="mgwOptions">
    <p>M3UA Interface (No 50035)</p>
  </list>
  <p name="name">MGW_A</p>
  <managedObject class="ATM" version="U5.0EP2" distName="PLMN-PLMN/MGW-219454/ATM-1" id="192614000003145148">
    <p name="lastSuccessfulUploadTimeStamp">21/07/15 01:32:40</p>
    <managedObject class="IFPG" version="A10TOP" distName="PLMN-PLMN/MGW-219454/ATM-1/IFPG-0" id="192614000003415034">
      <p name="prSectionSdhExchangeTerminalIndex">1</p>
      <p name="protectionSwitchingMode">REV</p>
      <p name="protocolVariant">MSP</p>
      <p name="switchingDirection">WO</p>
      <p name="waitToRestoreTime">300</p>
      <p name="woSectionSdhExchangeTerminalIndex">0</p>
    </managedObject>
    <managedObject class="IFPG" version="A10TOP" distName="PLMN-PLMN/MGW-219454/ATM-1/IFPG-1" id="192614000003415035">
      <p name="prSectionSdhExchangeTerminalIndex">3</p>
      <p name="protectionSwitchingMode">REV</p>
      <p name="protocolVariant">MSP</p>
      <p name="switchingDirection">WO</p>
      <p name="waitToRestoreTime">300</p>
      <p name="woSectionSdhExchangeTerminalIndex">2</p>
    </managedObject>
  </managedObject>
</managedObject>

这样的通用且简单的问题可以解决吗?我的文件包含大约 100,000 个托管对象,它们具有不同的类和不同的 distName 路径。

【问题讨论】:

  • 你能使用像 Saxon 9 这样的 XSLT 2.0 处理器吗?
  • 我可能不得不在我们的系统管理员那里争取它,但是是的。
  • 如果您无法升级到 XSLT 2.0,您使用的是哪个 XSLT 1.0 处理器?

标签: xml xslt


【解决方案1】:

更好的解释会很有用。盯着例子看,我看不出class 属性在这里起什么作用;似乎通过将最后一个/ 之前的distName 的子字符串与父级的整个distName 字符串进行比较,子级链接到了他们的父级。

除了使用上述规则寻找孤儿之外,也没有明显的方法可以确定“祖先”是谁。

另请注意,您的输入不是格式正确的 XML:您必须有一个根元素。

现在,如果您可以使用 XSLT 2.0,请尝试:

XSLT 2.0

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://www.example.com/my"
exclude-result-prefixes="my">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:function name="my:substring-before-last">
    <xsl:param name="string"/> 
    <xsl:param name="delimiter"/> 
    <xsl:value-of select="tokenize($string, $delimiter)[position()!=last()]" separator="{$delimiter}"/>
</xsl:function>

<xsl:key name="child" match="managedObject" use="my:substring-before-last(@distName, '/')" />
<xsl:key name="parent" match="managedObject" use="@distName" />

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

<xsl:template match="/input">
    <output>
        <!-- select progenitors -->
        <xsl:apply-templates select="managedObject[not(key('parent', my:substring-before-last(@distName, '/')))]" />
    </output>
</xsl:template>

<xsl:template match="managedObject">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <!-- select children -->
        <xsl:apply-templates select="key('child', @distName)"/> 
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

应用于以下格式正确的输入:

XML

<input>
    <managedObject class="MGW" version="U5.0EP2" distName="PLMN-PLMN/MGW-219454" id="192614000001726941">
      <list name="mgwOptions">
        <p>M3UA Interface (No 50035)</p>
      </list>
      <p name="name">MGW_A</p>
    </managedObject>
    <managedObject class="ATM" version="U5.0EP2" distName="PLMN-PLMN/MGW-219454/ATM-1" id="192614000003145148">
      <p name="lastSuccessfulUploadTimeStamp">21/07/15 01:32:40</p>
    </managedObject>
    <managedObject class="IFPG" version="A10TOP" distName="PLMN-PLMN/MGW-219454/ATM-1/IFPG-0" id="192614000003415034">
      <p name="prSectionSdhExchangeTerminalIndex">1</p>
      <p name="protectionSwitchingMode">REV</p>
      <p name="protocolVariant">MSP</p>
      <p name="switchingDirection">WO</p>
      <p name="waitToRestoreTime">300</p>
      <p name="woSectionSdhExchangeTerminalIndex">0</p>
    </managedObject>
    <managedObject class="IFPG" version="A10TOP" distName="PLMN-PLMN/MGW-219454/ATM-1/IFPG-1" id="192614000003415035">
      <p name="prSectionSdhExchangeTerminalIndex">3</p>
      <p name="protectionSwitchingMode">REV</p>
      <p name="protocolVariant">MSP</p>
      <p name="switchingDirection">WO</p>
      <p name="waitToRestoreTime">300</p>
      <p name="woSectionSdhExchangeTerminalIndex">2</p>
    </managedObject>
</input>

结果是:

<?xml version="1.0" encoding="utf-8"?>
<output>
   <managedObject class="MGW" version="U5.0EP2" distName="PLMN-PLMN/MGW-219454"
                  id="192614000001726941">
      <list name="mgwOptions">
         <p>M3UA Interface (No 50035)</p>
      </list>
      <p name="name">MGW_A</p>
      <managedObject class="ATM" version="U5.0EP2" distName="PLMN-PLMN/MGW-219454/ATM-1"
                     id="192614000003145148">
         <p name="lastSuccessfulUploadTimeStamp">21/07/15 01:32:40</p>
         <managedObject class="IFPG" version="A10TOP" distName="PLMN-PLMN/MGW-219454/ATM-1/IFPG-0"
                        id="192614000003415034">
            <p name="prSectionSdhExchangeTerminalIndex">1</p>
            <p name="protectionSwitchingMode">REV</p>
            <p name="protocolVariant">MSP</p>
            <p name="switchingDirection">WO</p>
            <p name="waitToRestoreTime">300</p>
            <p name="woSectionSdhExchangeTerminalIndex">0</p>
         </managedObject>
         <managedObject class="IFPG" version="A10TOP" distName="PLMN-PLMN/MGW-219454/ATM-1/IFPG-1"
                        id="192614000003415035">
            <p name="prSectionSdhExchangeTerminalIndex">3</p>
            <p name="protectionSwitchingMode">REV</p>
            <p name="protocolVariant">MSP</p>
            <p name="switchingDirection">WO</p>
            <p name="waitToRestoreTime">300</p>
            <p name="woSectionSdhExchangeTerminalIndex">2</p>
         </managedObject>
      </managedObject>
   </managedObject>
</output>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    相关资源
    最近更新 更多