使用 xslt 替换 xml 文件中元素中的值

Replace values in element in xml file using xslt

提问人:patrick 提问时间:9/8/2023 最后编辑:michael.hor257kpatrick 更新时间:9/8/2023 访问量:39

问:

我想删除 xml 文件中元素中值中不必要的文本,我想使用 XSLT 转换来执行此操作。

在这个示例文件中,我想删除元素值内部的特定标签,如 、 、 。<br><preffix><suffix><Value>

会有很多元素。而且我不想改变这个文件的结构,所以这应该像复制一样,但有逻辑来删除特定的文本。<Product>

我尝试使用模板和复制,但不知何故我无法将它们连接在一起。

如果你们中的任何人可以帮助我或给我提示我应该遵循,我将不胜感激。

<ProductInfo>
  <Products>
    <Product>
     <Name>xyz</Name>
     <Values>
        <Value><br/>test</Value> <-- remove <br/>
        <Value><preffix/>test2</Value> <-- remove <preffix>
        <Value><suffix/>test3</Value> <-- remove <suffix/>
     </Values>
    </Product>
  <Product>
     <Name>xyz</Name>
     <Values>
        <Value><br/>test</Value> <-- remove <br/>
        <Value><preffix/>test2</Value> <-- remove <preffix>
        <Value><suffix/>test3</Value> <-- remove <suffix/>
     </Values>
    </Product>
  </Products>
</ProductInfo>

输出文件应如下所示:

<ProductInfo>
  <Products>
    <Product>
     <Name>xyz</Name>
     <Values>
        <Value>test</Value>
        <Value>test2</Value>
        <Value>test3</Value>
     </Values>
    </Product>
  <Product>
     <Name>xyz</Name>
     <Values>
        <Value>test</Value> 
        <Value>test2</Value> 
        <Value>test3</Value> 
     </Values>
    </Product>
  </Products>
</ProductInfo>
xml xslt xslt-2.0

评论

0赞 michael.hor257k 9/8/2023
您希望删除的所有“标签”是否会像给定示例中那样为空?或者你可以有例如?<Value>Some <b>important</b> text.</Value>
0赞 patrick 9/8/2023
是的,这种情况可能会发生。
0赞 michael.hor257k 9/8/2023
那么结果应该是什么呢?

答:

2赞 michael.hor257k 9/8/2023 #1

以下样式表:

XSLT 1.0

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

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

<xsl:template match="Value">
    <xsl:copy>
        <xsl:value-of select="."/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

将通过仅返回 string-value 来删除元素中包含的任何标记 - 即“元素节点的所有文本节点后代的字符串值按文档顺序的串联”。Value

评论

0赞 patrick 9/8/2023
谢谢。是否有可能将它们替换为其他字符而不是删除它们?
0赞 michael.hor257k 9/8/2023
您需要编辑您的问题并详细解释应该用什么替换什么。或者 - 也许最好 - 发布一个新问题,因为这个问题已经有两个答案满足最初规定的要求。
0赞 michael.hor257k 9/8/2023
P.S. 请注意,您提到的那些“标签”实际上是元素。它们可以被文本取代,但它们本身不是“字符”。
1赞 michael.hor257k 9/8/2023
你不应该有。我已经把它回滚到@MadsHansen和我回答它时的样子。请发布一个新问题,并提出您的新要求。
0赞 patrick 9/8/2023
我创建了新的问题 stackoverflow.com/questions/77067827/...
1赞 Mads Hansen 9/8/2023 #2

您可以通过标识转换来实现此目的,其中包含与要删除/删除的内容匹配的其他空模板。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="@*|node()">      
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!--empty template matching the elements that we want to drop and not appear in the result-->
    <xsl:template match="Value/br | Value/prefix | Value/suffix"/>
    
</xsl:stylesheet>

您可以为每个匹配模式设置单独的空匹配模板,而不是使用联合。|

此外,如果要删除出现在元素内部的所有元素,则可以更通用地匹配 .ValueValue/*

评论

0赞 patrick 9/8/2023
非常感谢,但是这些前缀、后缀是如何被删除的呢?是否有可能将它们替换为其他字符而不是删除它们?
0赞 Mads Hansen 9/8/2023
您应该阅读标识模板和“推送样式”xml.com/pub/a/2005/07/06/tr.html 以了解事情是如何工作的。从本质上讲,当模板匹配时,模板中定义的内容决定了要做什么(有点像选择自己的冒险书)。如果它是一个空模板,则不执行任何操作。如果它与复制该节点的默认模板匹配,然后“推送”属性和子节点 - 处理器将查看哪些模板与这些项目匹配。
0赞 Mads Hansen 9/8/2023
它可以匹配默认模板,该模板将再次复制并推送,也可以与空模板匹配,该模板通过不执行任何操作来删除它。如果要匹配并将其更改为其他内容,请创建与之匹配的模板,然后执行任何操作。<br/>