0

我有一个 XML 文档,其中包含有关父实体的用户定义信息。我想创建一个 XSLT 将 XML 转换为当前用户定义的列表。XSLT 将需要忽略已删除的元素、添加新元素并保持用户定义的元素顺序。

示例输入 XML:

    <InventoryProperties>
      <InvProp Name="Weight"
               Type="Text"
               Alignment="Right">12500</InvProp>
      <InvProp Name="Length"
               Type="Text"
               Alignemnt="Right">20.2</InvProp>
      <InvProp Name="GVW"
               Type="Text"></InvProp>
   </InventoryProperties>

所以现在用户更改了收集的数据点,不再需要 GVW,而是在 Weight 和 Length 之间添加了 Height。到目前为止,我所做的是获得我想要的元素并留下我不再需要的元素:

<xsl:apply-templates select="InventoryProperties/InvProp[@Name = 'Weight']"/>

对当前定义的每个字段重复。这可以正常工作并按预期保持顺序。为了添加新元素,我正在尝试这样的事情:

<xsl:apply-templates  select="InventoryProperties[not(InvProp[@Name='Height'])]"/>
 <xsl:template name="HeightTemplate"
                match="InventoryProperties[not(InvProp[@Name='Height'])]">

    <xsl:apply-templates select="@*[not(name()='Height')]|node()"/>

    <Property LabelText="HelloWorld" />
  </xsl:template>

还有其他几个版本,但没有什么能产生我想要的东西:

<InventoryProperties>
  <Property LabelText="Weight"
            ControlType="Text">12500</Property>
  <Property LabelText="Height"
            ControlType="Text"></Property>
  <Property LabelText="Length"
            ControlType="Text">20.2</Property>
</InventoryProperties>

没有理由更改元素和属性名称,我只是试图整理哪些有效,哪些无效。

4

2 回答 2

0

我建议您为要添加到输出的每个字段名称调用一个命名模板。该命名模板将检查是否存在具有给定Name属性的元素,如果存在则复制它,如果不存在则创建具有正确属性的存根。

这表明了这个想法

<xsl:template match="InventoryProperties">
  <xsl:call-template name="inv-prop">
    <xsl:with-param name="name" select="'Weight'"/>
  </xsl:call-template>
  <xsl:call-template name="inv-prop">
    <xsl:with-param name="name" select="'Height'"/>
  </xsl:call-template>
  <xsl:call-template name="inv-prop">
    <xsl:with-param name="name" select="'Length'"/>
  </xsl:call-template>
</xsl:template>

<xsl:template name="inv-prop">
  <xsl:param name="name"/>
  <xsl:variable name="selection" select="InvProp[@Name = $name]"/>
  <xsl:choose>
    <xsl:when test="$selection">
      <xsl:copy-of select="$selection"/>
    </xsl:when>
    <xsl:otherwise>
      <InvProp Name="{$name}" Type="Text" Alignment="Right">
        <xsl:value-of select="InvProp[@Name = $name]"/>
      </InvProp>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

输出

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <InvProp Name="Weight" Type="Text" Alignment="Right">12500</InvProp>
   <InvProp Name="Height" Type="Text" Alignment="Right"/>
   <InvProp Name="Length" Type="Text" Alignemnt="Right">20.2</InvProp>
</root>
于 2013-05-22T16:39:12.770 回答
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>
    <!-- ingnore not wonted stuff -->
    <xsl:template match ="InvProp[@Name='GVW'] " />

    <!-- add missing stuff -->
    <xsl:template match ="InvProp[@Name='Weight'] ">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
        <xsl:if test="not(following-sibling::InvProp[@Name='Height'])" >
            <InvProp Name="Height" Type="Text" Alignment="Right"/>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
于 2013-05-22T19:26:45.507 回答