复制xml + 删除一些位置节点
Copy xml + remove some positional nodes
我需要在 BizTalk 中做一些事情。但它只是 xslt,所以我将其标记为 xslt 问题。
我在输入时收到 "multipart" 消息(正如您在下面的 xml 中看到的 "root & InputMessagePart_0"
我有以下 xml 作为输入。
<s0:Root xmlns:ns0="http://schemas.microsoft.com/BizTalk/2003/aggschema">
<InputMessagePart_0>
<ns0:parentnode xmlns:ns0="http://schemas.microsoft.com/namespace1" >
<ns0:childNode attribute1="test" attribute2="test">
<levelA xmlns="http://schemas.microsoft.com/namespace2"/>
</ns0:childNode>
<ns0:childNode2 Name="childNode2">
<levelA xmlns="http://schemas.microsoft.com/namespace3"/>
</ns0:childNode2>
<ns0:ChildNode3 Name="ChildNode3" id="2015-10-08-12.07.37.218960">
<ns0:levelA Name="levelA">
<ns0:data Name="Data" id="123456" type="A">
</ns0:data>
<ns0:data Name="Data" id="654321" type="B">
</ns0:data>
<ns0:levelAA id="910038265">
<ns0:repeatingItem id="910568755" >
<ns0:comm Name="Communication" id="910041726" numberOfDocuments="3">
<ns0:group Name="Group" id="12">
<ns0:doc archived="1" id="123" >
</ns0:doc>
<ns0:doc archived="1" id="321" >
</ns0:doc>
</ns0:group>
</ns0:comm>
</ns0:repeatingItem>
<ns0:repeatingItem id="123456789" >
<ns0:comm Name="Communication" id="910041726" numberOfDocuments="3">
<ns0:group conceptName="Group" id="34">
<ns0:doc archived="1" id="1234" >
</ns0:doc>
<ns0:doc archived="1" id="4321" >
</ns0:doc>
</ns0:group>
</ns0:comm>
</ns0:repeatingItem>
<ns0:repeatingItem id="987654321" >
<ns0:comm Name="Communication" id="910041726" numberOfDocuments="3">
<ns0:group Name="Group" id="56">
<ns0:doc archived="1" id="12345">
</ns0:doc>
</ns0:group>
</ns0:comm>
</ns0:repeatingItem>
</ns0:levelAA>
<ns0:OtherDoc id="123">
<ns0:Content/>
</ns0:OtherDoc>
<ns0:OtherDoc id="321">
<ns0:Content/>
</ns0:OtherDoc>
<ns0:OtherDoc id="1234">
<ns0:Content/>
</ns0:OtherDoc>
<ns0:OtherDoc id="4321">
<ns0:Content/>
</ns0:OtherDoc>
</ns0:data>
</ns0:ChildNode3>
</ns0:parentnode>
</InputMessagePart_0>
<InputMessagePart_1>
<ns7:MessageInformation xmlns:ns7="http://Schemas.RepeatingItemMessageInformation">
<RepeatingItemPosition>1</RepeatingItemPosition>
</ns7:MessageInformation>
</InputMessagePart_1>
我需要输出的东西
<ns0:parentnode xmlns:ns0="http://schemas.microsoft.com/namespace1" >
<ns0:childNode attribute1="test" attribute2="test">
<levelA xmlns="http://schemas.microsoft.com/namespace2"/>
</ns0:childNode>
<ns0:childNode2 Name="childNode2">
<levelA xmlns="http://schemas.microsoft.com/namespace3"/>
</ns0:childNode2>
<ns0:ChildNode3 Name="ChildNode3" id="2015-10-08-12.07.37.218960">
<ns0:levelA Name="levelA">
<ns0:data Name="Data" id="123456" type="A">
</ns0:data>
<ns0:data Name="Data" id="654321" type="B">
</ns0:data>
<ns0:levelAA id="910038265">
<ns0:repeatingItem id="910568755" >
<ns0:comm Name="Communication" id="910041726" numberOfDocuments="3">
<ns0:group Name="Group" id="12">
<ns0:doc archived="0" id="123" >
</ns0:doc>
<ns0:doc archived="0" id="321" >
</ns0:doc>
</ns0:group>
</ns0:comm>
</ns0:repeatingItem>
</ns0:levelAA>
<ns0:OtherDoc id="123">
<ns0:Content/>
</ns0:OtherDoc>
<ns0:OtherDoc id="321">
<ns0:Content/>
</ns0:OtherDoc>
</ns0:data>
</ns0:ChildNode3>
我会解释它需要什么。
1) 复制"InputMessagePart_0"
下的所有内容
那么例外:)
a) 我只需要具有特定位置的 repeatingItem(在输入中您会看到 "InputMessagePart_1/MessageInformation/repeatingItemPosition")。所以在这个例子的输出中我们只需要 repeatingItem “1”。它始终是 1 个数字。因此,当我们在 BizTalk 编排中循环时,它将是 1 或 2 或 3 或 ....
b) 同样在 "repeatingItem/comm/group/doc" 下,属性 "archived" 应始终设置为“0”。
c) 我不知道这是否可能。在 "OtherDoc" 中我们有一些内容(base64 生成的东西)。因为我们删除了其他重复项,所以并非所有 "Otherdoc" 项都需要。仅与 repeatingItem 文档中具有相同 ID 的那些。 (但这甚至可以检查重复项,然后删除我们不需要的 OtherDoc。
我已经尝试了一些东西。但我无法让它工作。下面你可以找到我用过的。但我还不是(我希望)xslt 专家。 :)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0 s1" version="1.0"
xmlns:ns0="http://schemas.microsoft.com/namespace1"
xmlns:s0="http://schemas.microsoft.com/BizTalk/2003/aggschema"
xmlns:s7="http://Schemas.RepeatingMessageInformation">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<!-- Copy the n-th repeatingItem element-->
<xsl:template match="ns0:repeatingItem[number(s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition/text())]">
<xsl:apply-templates select="current()"/>
</xsl:template>
<!-- Don't copy the other repeatingItem elements-->
<xsl:template match="ns0:repeatingItem[position()!=s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition/text()]"/>
<xsl:template match="ns0:doc">
<ns0:doc>
<xsl:copy-of select="@*[local-name()!='archived']"/>
<xsl:attribute name="archived">0</xsl:attribute>
</ns0:doc>
</xsl:template>
</xsl:stylesheet>
在谓词内部,上下文节点发生变化,因此 match="ns0:repeatingItem[number(s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition/text())]"
需要 match="ns0:repeatingItem[number(/s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition/text())]"
以确保谓词不会查找 ns0:repeatingItem
的子 s0:Root
。
但我完全不明白您为什么需要该模板,如果您想复制该元素,那么您已有的身份转换模板将进行复制。我认为 <xsl:apply-templates select="current()"/>
会导致无限递归,所以这不太可能是你想要的。
然后将<xsl:template match="ns0:repeatingItem[position()!=s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition/text()]"/>
更正为<xsl:template match="ns0:repeatingItem[position()!=/s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition]"/>
。
最后我觉得你要补充
<xsl:template match="ns0:ChildNode3/ns0:levelA/ns0:OtherDoc[not(@id = ancestor::ns0:ChildNode3/descendant::ns0:repeatingItem[number(/s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition)]//ns0:OtherDoc/@id)]"/>
综合考虑这些建议并解决我得到的元素名称或命名空间名称的一些问题
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0 " version="1.0"
xmlns:ns0="http://schemas.microsoft.com/namespace1"
xmlns:s0="http://schemas.microsoft.com/BizTalk/2003/aggschema"
xmlns:s7="http://Schemas.RepeatingItemMessageInformation">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="s0:Root">
<xsl:apply-templates select="InputMessagePart_0/node()"/>
</xsl:template>
<!-- Don't copy the other repeatingItem elements-->
<xsl:template match="ns0:repeatingItem[position()!=/s0:Root/InputMessagePart_1/s7:MessageInformation/RepeatingItemPosition]"/>
<xsl:template match="ns0:doc">
<ns0:doc>
<xsl:copy-of select="@*[local-name()!='archived']"/>
<xsl:attribute name="archived">0</xsl:attribute>
</ns0:doc>
</xsl:template>
<xsl:template match="ns0:ChildNode3/ns0:levelA/ns0:OtherDoc[not(@id = ancestor::ns0:ChildNode3/descendant::ns0:repeatingItem[number(/s0:Root/InputMessagePart_1/s7:MessageInformation/RepeatingItemPosition)]//ns0:doc/@id)]"/>
</xsl:stylesheet>
我需要在 BizTalk 中做一些事情。但它只是 xslt,所以我将其标记为 xslt 问题。
我在输入时收到 "multipart" 消息(正如您在下面的 xml 中看到的 "root & InputMessagePart_0"
我有以下 xml 作为输入。
<s0:Root xmlns:ns0="http://schemas.microsoft.com/BizTalk/2003/aggschema">
<InputMessagePart_0>
<ns0:parentnode xmlns:ns0="http://schemas.microsoft.com/namespace1" >
<ns0:childNode attribute1="test" attribute2="test">
<levelA xmlns="http://schemas.microsoft.com/namespace2"/>
</ns0:childNode>
<ns0:childNode2 Name="childNode2">
<levelA xmlns="http://schemas.microsoft.com/namespace3"/>
</ns0:childNode2>
<ns0:ChildNode3 Name="ChildNode3" id="2015-10-08-12.07.37.218960">
<ns0:levelA Name="levelA">
<ns0:data Name="Data" id="123456" type="A">
</ns0:data>
<ns0:data Name="Data" id="654321" type="B">
</ns0:data>
<ns0:levelAA id="910038265">
<ns0:repeatingItem id="910568755" >
<ns0:comm Name="Communication" id="910041726" numberOfDocuments="3">
<ns0:group Name="Group" id="12">
<ns0:doc archived="1" id="123" >
</ns0:doc>
<ns0:doc archived="1" id="321" >
</ns0:doc>
</ns0:group>
</ns0:comm>
</ns0:repeatingItem>
<ns0:repeatingItem id="123456789" >
<ns0:comm Name="Communication" id="910041726" numberOfDocuments="3">
<ns0:group conceptName="Group" id="34">
<ns0:doc archived="1" id="1234" >
</ns0:doc>
<ns0:doc archived="1" id="4321" >
</ns0:doc>
</ns0:group>
</ns0:comm>
</ns0:repeatingItem>
<ns0:repeatingItem id="987654321" >
<ns0:comm Name="Communication" id="910041726" numberOfDocuments="3">
<ns0:group Name="Group" id="56">
<ns0:doc archived="1" id="12345">
</ns0:doc>
</ns0:group>
</ns0:comm>
</ns0:repeatingItem>
</ns0:levelAA>
<ns0:OtherDoc id="123">
<ns0:Content/>
</ns0:OtherDoc>
<ns0:OtherDoc id="321">
<ns0:Content/>
</ns0:OtherDoc>
<ns0:OtherDoc id="1234">
<ns0:Content/>
</ns0:OtherDoc>
<ns0:OtherDoc id="4321">
<ns0:Content/>
</ns0:OtherDoc>
</ns0:data>
</ns0:ChildNode3>
</ns0:parentnode>
</InputMessagePart_0>
<InputMessagePart_1>
<ns7:MessageInformation xmlns:ns7="http://Schemas.RepeatingItemMessageInformation">
<RepeatingItemPosition>1</RepeatingItemPosition>
</ns7:MessageInformation>
</InputMessagePart_1>
我需要输出的东西
<ns0:parentnode xmlns:ns0="http://schemas.microsoft.com/namespace1" >
<ns0:childNode attribute1="test" attribute2="test">
<levelA xmlns="http://schemas.microsoft.com/namespace2"/>
</ns0:childNode>
<ns0:childNode2 Name="childNode2">
<levelA xmlns="http://schemas.microsoft.com/namespace3"/>
</ns0:childNode2>
<ns0:ChildNode3 Name="ChildNode3" id="2015-10-08-12.07.37.218960">
<ns0:levelA Name="levelA">
<ns0:data Name="Data" id="123456" type="A">
</ns0:data>
<ns0:data Name="Data" id="654321" type="B">
</ns0:data>
<ns0:levelAA id="910038265">
<ns0:repeatingItem id="910568755" >
<ns0:comm Name="Communication" id="910041726" numberOfDocuments="3">
<ns0:group Name="Group" id="12">
<ns0:doc archived="0" id="123" >
</ns0:doc>
<ns0:doc archived="0" id="321" >
</ns0:doc>
</ns0:group>
</ns0:comm>
</ns0:repeatingItem>
</ns0:levelAA>
<ns0:OtherDoc id="123">
<ns0:Content/>
</ns0:OtherDoc>
<ns0:OtherDoc id="321">
<ns0:Content/>
</ns0:OtherDoc>
</ns0:data>
</ns0:ChildNode3>
我会解释它需要什么。
1) 复制"InputMessagePart_0"
下的所有内容那么例外:)
a) 我只需要具有特定位置的 repeatingItem(在输入中您会看到 "InputMessagePart_1/MessageInformation/repeatingItemPosition")。所以在这个例子的输出中我们只需要 repeatingItem “1”。它始终是 1 个数字。因此,当我们在 BizTalk 编排中循环时,它将是 1 或 2 或 3 或 ....
b) 同样在 "repeatingItem/comm/group/doc" 下,属性 "archived" 应始终设置为“0”。
c) 我不知道这是否可能。在 "OtherDoc" 中我们有一些内容(base64 生成的东西)。因为我们删除了其他重复项,所以并非所有 "Otherdoc" 项都需要。仅与 repeatingItem 文档中具有相同 ID 的那些。 (但这甚至可以检查重复项,然后删除我们不需要的 OtherDoc。
我已经尝试了一些东西。但我无法让它工作。下面你可以找到我用过的。但我还不是(我希望)xslt 专家。 :)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0 s1" version="1.0"
xmlns:ns0="http://schemas.microsoft.com/namespace1"
xmlns:s0="http://schemas.microsoft.com/BizTalk/2003/aggschema"
xmlns:s7="http://Schemas.RepeatingMessageInformation">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<!-- Copy the n-th repeatingItem element-->
<xsl:template match="ns0:repeatingItem[number(s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition/text())]">
<xsl:apply-templates select="current()"/>
</xsl:template>
<!-- Don't copy the other repeatingItem elements-->
<xsl:template match="ns0:repeatingItem[position()!=s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition/text()]"/>
<xsl:template match="ns0:doc">
<ns0:doc>
<xsl:copy-of select="@*[local-name()!='archived']"/>
<xsl:attribute name="archived">0</xsl:attribute>
</ns0:doc>
</xsl:template>
</xsl:stylesheet>
在谓词内部,上下文节点发生变化,因此 match="ns0:repeatingItem[number(s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition/text())]"
需要 match="ns0:repeatingItem[number(/s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition/text())]"
以确保谓词不会查找 ns0:repeatingItem
的子 s0:Root
。
但我完全不明白您为什么需要该模板,如果您想复制该元素,那么您已有的身份转换模板将进行复制。我认为 <xsl:apply-templates select="current()"/>
会导致无限递归,所以这不太可能是你想要的。
然后将<xsl:template match="ns0:repeatingItem[position()!=s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition/text()]"/>
更正为<xsl:template match="ns0:repeatingItem[position()!=/s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition]"/>
。
最后我觉得你要补充
<xsl:template match="ns0:ChildNode3/ns0:levelA/ns0:OtherDoc[not(@id = ancestor::ns0:ChildNode3/descendant::ns0:repeatingItem[number(/s0:Root/InputMessagePart_1/s7:MessageInformation/repeatingItemPosition)]//ns0:OtherDoc/@id)]"/>
综合考虑这些建议并解决我得到的元素名称或命名空间名称的一些问题
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0 " version="1.0"
xmlns:ns0="http://schemas.microsoft.com/namespace1"
xmlns:s0="http://schemas.microsoft.com/BizTalk/2003/aggschema"
xmlns:s7="http://Schemas.RepeatingItemMessageInformation">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="s0:Root">
<xsl:apply-templates select="InputMessagePart_0/node()"/>
</xsl:template>
<!-- Don't copy the other repeatingItem elements-->
<xsl:template match="ns0:repeatingItem[position()!=/s0:Root/InputMessagePart_1/s7:MessageInformation/RepeatingItemPosition]"/>
<xsl:template match="ns0:doc">
<ns0:doc>
<xsl:copy-of select="@*[local-name()!='archived']"/>
<xsl:attribute name="archived">0</xsl:attribute>
</ns0:doc>
</xsl:template>
<xsl:template match="ns0:ChildNode3/ns0:levelA/ns0:OtherDoc[not(@id = ancestor::ns0:ChildNode3/descendant::ns0:repeatingItem[number(/s0:Root/InputMessagePart_1/s7:MessageInformation/RepeatingItemPosition)]//ns0:doc/@id)]"/>
</xsl:stylesheet>