【问题标题】:XSLT & XPath: how to change XML file in the most effective way?XSLT & XPath:如何以最有效的方式更改 XML 文件?
【发布时间】:2010-02-04 14:36:20
【问题描述】:

我是 XSLT 和 XPath 的新手,所以请原谅我这个简单的问题。

我有以下 XML 文件:

<?xml version="1.0"?>
    <Configuration serviceName="Just Service" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
      <Page name="Books">
        <Instances count="5" />
        <ConfigurationSettings>
          <Setting name="index" value="true" />
          <Setting name="number" value="value1" />
          <Setting name="bookstorage" value="value2"/>
        </ConfigurationSettings>
      </Page>
      <Page name="Magazines">
        <Instances count="7" />
        <ConfigurationSettings>
          <Setting name="index" value="false" />
          <Setting name="number" value="value1" />
          <Setting name="magazinestorage" value="value3"/>
        </ConfigurationSettings>
      </Page>
    </Configuration>

我只想更改以下值 ...

value1 - number(在两个地方); value2 - 用于图书存储; value3 - 用于杂志存储;

...并保持所有其他内容不变。

为此,我想使用 msxsl.exe(Microsoft 命令行实用程序)。您能否给我一个 XSLT 样式表示例的提示?如何以最有效的方式使用 XSLT 处理初始 XML 文件?

谢谢, 拉克

【问题讨论】:

    标签: xml xslt xpath


    【解决方案1】:

    在 XSLT 中执行此操作的方法是使用一个简单地复制文档内容的默认模板,例如:

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

    然后将模板添加到您的样式表中,该模板将匹配您要更改的特定节点。这些节点在匹配时将覆盖上面的默认复制模板。例如,如果您希望元素 Setting 的每个数字属性都具有值 314,您可以添加一个模板:

    <xsl:template match="Setting/@number">
        <-- this copies in an attribute 'number' in place; with different contents -->
        <xsl:copy>314</xsl:copy>    
    <xsl:template/>
    

    这两个模板,以及您想要进行的其他替换的任何其他模板,都将以任意顺序出现在您的样式表中

    【讨论】:

      【解决方案2】:

      这是一个示例 XSLT 1.0 样式表,它采用三个带有新值的参数:

      <xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:sc="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration"
        exclude-result-prefixes="sc"
        version="1.0">
      
        <xsl:param name="p1" select="'foo'"/>
        <xsl:param name="p2" select="'bar'"/>
        <xsl:param name="p3" select="'foobar'"/>
      
        <xsl:template match="@* | node()">
          <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
          </xsl:copy>
        </xsl:template>
      
        <xsl:template match="sc:Setting[@name = 'number']/@value">
          <xsl:attribute name="{name()}">
            <xsl:value-of select="$p1"/>
          </xsl:attribute>
        </xsl:template>
      
        <xsl:template match="sc:Setting[@name = 'bookstorage']/@value">
          <xsl:attribute name="{name()}">
            <xsl:value-of select="$p2"/>
          </xsl:attribute>
        </xsl:template>
      
        <xsl:template match="sc:Setting[@name = 'magazinestorage']/@value">
          <xsl:attribute name="{name()}">
            <xsl:value-of select="$p3"/>
          </xsl:attribute>
        </xsl:template>
      
      </xsl:stylesheet>
      

      【讨论】:

        【解决方案3】:

        我担心这个用例,并且使用 xslt 从头开始​​构建一个全新的文档会更容易。或者使用您选择的编程语言,您可以读取 DOM 树并仅更改那些变量(如果需要,我可以为 Java 展示这一点)。

        在其他用例中,您可以让原始 xml 通过处理。查看here了解更多信息。

        【讨论】:

        • 卡鲁塞尔,感谢您的回答。实际上,我不介意它是否是从头开始的新文档。 msxsl.exe 有这个选项。或者我几乎无法重定向输出。所以让它成为新文件。那么在这种情况下 XSTLT 会是什么样子呢?谢谢,
        猜你喜欢
        • 1970-01-01
        • 2013-11-15
        • 1970-01-01
        • 1970-01-01
        • 2019-07-28
        • 1970-01-01
        • 2012-07-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多